aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorGautham Goli2017-10-12 00:29:19 +0530
committerGautham Goli2017-10-13 19:50:46 +0530
commit7fa51f71f1a8a21b905bafc1fb4106f0222d654f (patch)
tree098d2477a8262a5770310fed4693da31c4392e1c /Library
parentafdd0e2437426ec85ff86e5b7562d3a6a69ba3e5 (diff)
parent56458f03fcc68ef6d8ee3ee4a7c1d16021aa5800 (diff)
downloadbrew-7fa51f71f1a8a21b905bafc1fb4106f0222d654f.tar.bz2
Merge branch 'master' into audit_line_rubocop_part_4_rebase_attempt_1
Diffstat (limited to 'Library')
-rw-r--r--Library/.rubocop.yml23
-rw-r--r--Library/Homebrew/.rubocop.yml30
-rw-r--r--Library/Homebrew/.rubocop_todo.yml145
-rwxr-xr-xLibrary/Homebrew/.simplecov37
-rw-r--r--Library/Homebrew/brew.rb30
-rw-r--r--Library/Homebrew/brew.sh11
-rw-r--r--Library/Homebrew/build.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc.rb1
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact.rb42
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb109
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb42
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb (renamed from Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb)146
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/artifact.rb31
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/base.rb80
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/binary.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/installer.rb97
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/moved.rb52
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb32
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/pkg.rb65
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb20
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/relocated.rb82
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb20
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/suite.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb58
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb8
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/zap.rb8
-rw-r--r--Library/Homebrew/cask/lib/hbc/audit.rb30
-rw-r--r--Library/Homebrew/cask/lib/hbc/auditor.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/cask.rb10
-rw-r--r--Library/Homebrew/cask/lib/hbc/cask_loader.rb43
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb47
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/cat.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/edit.rb19
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/fetch.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/info.rb18
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/install.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb26
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb74
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/list.rb16
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/reinstall.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/search.rb22
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/uninstall.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/zap.rb4
-rw-r--r--Library/Homebrew/cask/lib/hbc/container.rb3
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/base.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/criteria.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/directory.rb24
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/executable.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/naked.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/container/svn_repository.rb15
-rw-r--r--Library/Homebrew/cask/lib/hbc/download_strategy.rb85
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl.rb153
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/appcast.rb20
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/base.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/caveats.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/conflicts_with.rb19
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/gpg.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/installer.rb32
-rw-r--r--Library/Homebrew/cask/lib/hbc/dsl/version.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/exceptions.rb13
-rw-r--r--Library/Homebrew/cask/lib/hbc/installer.rb43
-rw-r--r--Library/Homebrew/cask/lib/hbc/staged.rb2
-rw-r--r--Library/Homebrew/cask/lib/hbc/system_command.rb6
-rw-r--r--Library/Homebrew/cask/lib/hbc/underscore_supporting_uri.rb28
-rw-r--r--Library/Homebrew/cask/lib/hbc/url.rb13
-rw-r--r--Library/Homebrew/cask/lib/hbc/verify/gpg.rb2
-rw-r--r--Library/Homebrew/caveats.rb2
-rw-r--r--Library/Homebrew/cleanup.rb8
-rw-r--r--Library/Homebrew/cmd/deps.rb134
-rw-r--r--Library/Homebrew/cmd/fetch.rb6
-rw-r--r--Library/Homebrew/cmd/install.rb2
-rw-r--r--Library/Homebrew/cmd/irb.rb8
-rw-r--r--Library/Homebrew/cmd/list.rb10
-rw-r--r--Library/Homebrew/cmd/pin.rb3
-rw-r--r--Library/Homebrew/cmd/postinstall.rb2
-rw-r--r--Library/Homebrew/cmd/prune.rb2
-rw-r--r--Library/Homebrew/cmd/reinstall.rb4
-rw-r--r--Library/Homebrew/cmd/search.rb31
-rw-r--r--Library/Homebrew/cmd/style.rb5
-rw-r--r--Library/Homebrew/cmd/tap-info.rb4
-rw-r--r--Library/Homebrew/cmd/tap.rb3
-rw-r--r--Library/Homebrew/cmd/unlinkapps.rb2
-rw-r--r--Library/Homebrew/cmd/unpin.rb4
-rw-r--r--Library/Homebrew/cmd/update-report.rb9
-rw-r--r--Library/Homebrew/cmd/update.sh7
-rw-r--r--Library/Homebrew/cmd/upgrade.rb1
-rw-r--r--Library/Homebrew/cmd/uses.rb6
-rw-r--r--Library/Homebrew/cmd/vendor-install.sh21
-rw-r--r--Library/Homebrew/compat/ENV/shared.rb4
-rw-r--r--Library/Homebrew/compat/formula_specialties.rb2
-rw-r--r--Library/Homebrew/constants.rb6
-rw-r--r--Library/Homebrew/debrew.rb8
-rw-r--r--Library/Homebrew/debrew/irb.rb5
-rw-r--r--Library/Homebrew/dependency.rb4
-rw-r--r--Library/Homebrew/dependency_collector.rb11
-rw-r--r--Library/Homebrew/descriptions.rb4
-rw-r--r--Library/Homebrew/dev-cmd/aspell-dictionaries.rb5
-rw-r--r--Library/Homebrew/dev-cmd/audit.rb173
-rw-r--r--Library/Homebrew/dev-cmd/bottle.rb15
-rw-r--r--Library/Homebrew/dev-cmd/bump-formula-pr.rb20
-rw-r--r--Library/Homebrew/dev-cmd/man.rb9
-rw-r--r--Library/Homebrew/dev-cmd/mirror.rb10
-rw-r--r--Library/Homebrew/dev-cmd/pull.rb26
-rw-r--r--Library/Homebrew/dev-cmd/release-notes.rb4
-rw-r--r--Library/Homebrew/dev-cmd/test.rb4
-rw-r--r--Library/Homebrew/dev-cmd/update-test.rb2
-rw-r--r--Library/Homebrew/development_tools.rb2
-rw-r--r--Library/Homebrew/diagnostic.rb26
-rw-r--r--Library/Homebrew/download_strategy.rb135
-rw-r--r--Library/Homebrew/exceptions.rb12
-rw-r--r--Library/Homebrew/extend/ARGV.rb6
-rw-r--r--Library/Homebrew/extend/ENV.rb2
-rw-r--r--Library/Homebrew/extend/ENV/shared.rb4
-rw-r--r--Library/Homebrew/extend/ENV/std.rb4
-rw-r--r--Library/Homebrew/extend/ENV/super.rb10
-rw-r--r--Library/Homebrew/extend/cachable.rb9
-rw-r--r--Library/Homebrew/extend/fileutils.rb2
-rw-r--r--Library/Homebrew/extend/os/mac/development_tools.rb17
-rw-r--r--Library/Homebrew/extend/os/mac/diagnostic.rb5
-rw-r--r--Library/Homebrew/extend/os/mac/extend/ENV/super.rb12
-rw-r--r--Library/Homebrew/extend/os/mac/formula_cellar_checks.rb16
-rw-r--r--Library/Homebrew/extend/os/mac/hardware/cpu.rb2
-rw-r--r--Library/Homebrew/extend/pathname.rb4
-rw-r--r--Library/Homebrew/extend/string.rb2
-rw-r--r--Library/Homebrew/formula.rb81
-rw-r--r--Library/Homebrew/formula_installer.rb78
-rw-r--r--Library/Homebrew/formula_versions.rb2
-rw-r--r--Library/Homebrew/formulary.rb29
-rw-r--r--Library/Homebrew/global.rb6
-rw-r--r--Library/Homebrew/gpg.rb24
-rw-r--r--Library/Homebrew/install_renamed.rb8
-rw-r--r--Library/Homebrew/keg.rb7
-rw-r--r--Library/Homebrew/keg_relocate.rb3
-rw-r--r--Library/Homebrew/language/python.rb2
-rw-r--r--Library/Homebrew/locale.rb8
-rw-r--r--Library/Homebrew/manpages/brew-cask.1.md20
-rw-r--r--Library/Homebrew/migrator.rb6
-rw-r--r--Library/Homebrew/missing_formula.rb13
-rw-r--r--Library/Homebrew/official_taps.rb2
-rw-r--r--Library/Homebrew/options.rb24
-rw-r--r--Library/Homebrew/os/mac.rb16
-rw-r--r--Library/Homebrew/os/mac/linkage_checker.rb19
-rw-r--r--Library/Homebrew/os/mac/version.rb1
-rw-r--r--Library/Homebrew/os/mac/xcode.rb4
-rw-r--r--Library/Homebrew/patch.rb12
-rw-r--r--Library/Homebrew/pkg_version.rb2
-rw-r--r--Library/Homebrew/postinstall.rb2
-rw-r--r--Library/Homebrew/readall.rb2
-rw-r--r--Library/Homebrew/requirements/gpg2_requirement.rb8
-rw-r--r--Library/Homebrew/requirements/java_requirement.rb4
-rw-r--r--Library/Homebrew/requirements/ruby_requirement.rb4
-rw-r--r--Library/Homebrew/rubocops.rb1
-rw-r--r--Library/Homebrew/rubocops/class_cop.rb41
-rw-r--r--Library/Homebrew/rubocops/components_order_cop.rb4
-rw-r--r--Library/Homebrew/rubocops/conflicts_cop.rb2
-rw-r--r--Library/Homebrew/rubocops/extend/formula_cop.rb54
-rw-r--r--Library/Homebrew/rubocops/lines_cop.rb168
-rw-r--r--Library/Homebrew/rubocops/patches_cop.rb32
-rw-r--r--Library/Homebrew/rubocops/urls_cop.rb6
-rw-r--r--Library/Homebrew/sandbox.rb8
-rwxr-xr-xLibrary/Homebrew/shims/super/cc2
-rwxr-xr-xLibrary/Homebrew/shims/super/make9
-rw-r--r--Library/Homebrew/software_spec.rb16
-rw-r--r--Library/Homebrew/system_config.rb2
-rw-r--r--Library/Homebrew/tab.rb14
-rw-r--r--Library/Homebrew/tap.rb18
-rw-r--r--Library/Homebrew/test.rb2
-rw-r--r--Library/Homebrew/test/Gemfile4
-rw-r--r--Library/Homebrew/test/Gemfile.lock22
-rw-r--r--Library/Homebrew/test/bottle_hooks_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/accessibility_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/artifact/alt_target_spec.rb8
-rw-r--r--Library/Homebrew/test/cask/artifact/app_spec.rb23
-rw-r--r--Library/Homebrew/test/cask/artifact/binary_spec.rb37
-rw-r--r--Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb18
-rw-r--r--Library/Homebrew/test/cask/artifact/nested_container_spec.rb6
-rw-r--r--Library/Homebrew/test/cask/artifact/pkg_spec.rb12
-rw-r--r--Library/Homebrew/test/cask/artifact/postflight_block_spec.rb8
-rw-r--r--Library/Homebrew/test/cask/artifact/preflight_block_spec.rb8
-rw-r--r--Library/Homebrew/test/cask/artifact/suite_spec.rb12
-rw-r--r--Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb10
-rw-r--r--Library/Homebrew/test/cask/artifact/two_apps_incorrect_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/artifact/uninstall_no_zap_spec.rb4
-rw-r--r--Library/Homebrew/test/cask/artifact/uninstall_zap_shared_examples.rb30
-rw-r--r--Library/Homebrew/test/cask/audit_spec.rb9
-rw-r--r--Library/Homebrew/test/cask/cask_loader/from_content_loader_spec.rb57
-rw-r--r--Library/Homebrew/test/cask/cask_loader/from_uri_loader_spec.rb21
-rw-r--r--Library/Homebrew/test/cask/cask_spec.rb34
-rw-r--r--Library/Homebrew/test/cask/cli/audit_spec.rb20
-rw-r--r--Library/Homebrew/test/cask/cli/cat_spec.rb37
-rw-r--r--Library/Homebrew/test/cask/cli/cleanup_spec.rb4
-rw-r--r--Library/Homebrew/test/cask/cli/create_spec.rb30
-rw-r--r--Library/Homebrew/test/cask/cli/doctor_spec.rb4
-rw-r--r--Library/Homebrew/test/cask/cli/edit_spec.rb24
-rw-r--r--Library/Homebrew/test/cask/cli/fetch_spec.rb36
-rw-r--r--Library/Homebrew/test/cask/cli/home_spec.rb4
-rw-r--r--Library/Homebrew/test/cask/cli/info_spec.rb70
-rw-r--r--Library/Homebrew/test/cask/cli/install_spec.rb86
-rw-r--r--Library/Homebrew/test/cask/cli/list_spec.rb40
-rw-r--r--Library/Homebrew/test/cask/cli/options_spec.rb32
-rw-r--r--Library/Homebrew/test/cask/cli/outdated_spec.rb16
-rw-r--r--Library/Homebrew/test/cask/cli/reinstall_spec.rb14
-rw-r--r--Library/Homebrew/test/cask/cli/search_spec.rb57
-rw-r--r--Library/Homebrew/test/cask/cli/shared_examples/invalid_option.rb15
-rw-r--r--Library/Homebrew/test/cask/cli/shared_examples/requires_cask_token.rb9
-rw-r--r--Library/Homebrew/test/cask/cli/style_spec.rb4
-rw-r--r--Library/Homebrew/test/cask/cli/uninstall_spec.rb65
-rw-r--r--Library/Homebrew/test/cask/cli/zap_spec.rb33
-rw-r--r--Library/Homebrew/test/cask/conflicts_with_spec.rb23
-rw-r--r--Library/Homebrew/test/cask/container/dmg_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/depends_on_spec.rb29
-rw-r--r--Library/Homebrew/test/cask/download_strategy_spec.rb66
-rw-r--r--Library/Homebrew/test/cask/dsl/appcast_spec.rb13
-rw-r--r--Library/Homebrew/test/cask/dsl/caveats_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/dsl/postflight_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/dsl/preflight_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/dsl/uninstall_postflight_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/dsl/uninstall_preflight_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/dsl_spec.rb83
-rw-r--r--Library/Homebrew/test/cask/installer_spec.rb48
-rw-r--r--Library/Homebrew/test/cask/staged_spec.rb2
-rw-r--r--Library/Homebrew/test/cask/underscore_supporting_uri_spec.rb14
-rw-r--r--Library/Homebrew/test/cleanup_spec.rb132
-rw-r--r--Library/Homebrew/test/cmd/commands_spec.rb2
-rw-r--r--Library/Homebrew/test/cmd/home_spec.rb6
-rw-r--r--Library/Homebrew/test/cmd/search_remote_tap_spec.rb3
-rw-r--r--Library/Homebrew/test/cmd/search_spec.rb14
-rw-r--r--Library/Homebrew/test/dependency_expansion_spec.rb2
-rw-r--r--Library/Homebrew/test/dev-cmd/audit_spec.rb64
-rw-r--r--Library/Homebrew/test/download_strategies_spec.rb11
-rw-r--r--Library/Homebrew/test/exceptions_spec.rb6
-rw-r--r--Library/Homebrew/test/formula_installer_spec.rb2
-rw-r--r--Library/Homebrew/test/formulary_spec.rb2
-rw-r--r--Library/Homebrew/test/locale_spec.rb4
-rw-r--r--Library/Homebrew/test/missing_formula_spec.rb6
-rw-r--r--Library/Homebrew/test/os/mac/diagnostic_spec.rb11
-rw-r--r--Library/Homebrew/test/pathname_spec.rb2
-rw-r--r--Library/Homebrew/test/requirement_spec.rb4
-rw-r--r--Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb4
-rw-r--r--Library/Homebrew/test/rubocops/caveats_cop_spec.rb2
-rw-r--r--Library/Homebrew/test/rubocops/checksum_cop_spec.rb12
-rw-r--r--Library/Homebrew/test/rubocops/class_cop_spec.rb81
-rw-r--r--Library/Homebrew/test/rubocops/components_order_cop_spec.rb12
-rw-r--r--Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb6
-rw-r--r--Library/Homebrew/test/rubocops/conflicts_cop_spec.rb4
-rw-r--r--Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb20
-rw-r--r--Library/Homebrew/test/rubocops/homepage_cop_spec.rb6
-rw-r--r--Library/Homebrew/test/rubocops/lines_cop_spec.rb190
-rw-r--r--Library/Homebrew/test/rubocops/options_cop_spec.rb10
-rw-r--r--Library/Homebrew/test/rubocops/patches_cop_spec.rb202
-rw-r--r--Library/Homebrew/test/rubocops/text_cop_spec.rb66
-rw-r--r--Library/Homebrew/test/rubocops/urls_cop_spec.rb31
-rw-r--r--Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.yosemite.bottle.tar.gzbin1379 -> 1731 bytes
-rw-r--r--Library/Homebrew/test/support/fixtures/cask/Casks/with-conflicts-with.rb2
-rw-r--r--Library/Homebrew/test/support/fixtures/cask/Casks/with-languages.rb18
-rw-r--r--Library/Homebrew/test/support/fixtures/cask/Casks/without-languages.rb9
-rw-r--r--Library/Homebrew/test/support/fixtures/testball_bottle.rb2
-rw-r--r--Library/Homebrew/test/support/fixtures/third-party/Casks/third-party-cask.rb9
-rw-r--r--Library/Homebrew/test/support/helper/fixtures.rb4
-rw-r--r--Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb8
-rw-r--r--Library/Homebrew/test/utils/analytics_spec.rb88
-rw-r--r--Library/Homebrew/test/utils/git_spec.rb150
-rw-r--r--Library/Homebrew/test/utils/github_spec.rb30
-rw-r--r--Library/Homebrew/test/utils/svn_spec.rb39
-rw-r--r--Library/Homebrew/test/utils_spec.rb29
-rw-r--r--Library/Homebrew/test/version_spec.rb19
-rw-r--r--Library/Homebrew/utils.rb22
-rw-r--r--Library/Homebrew/utils/analytics.rb5
-rw-r--r--Library/Homebrew/utils/bottles.rb13
-rw-r--r--Library/Homebrew/utils/curl.rb51
-rw-r--r--Library/Homebrew/utils/fork.rb9
-rw-r--r--Library/Homebrew/utils/git.rb23
-rw-r--r--Library/Homebrew/utils/github.rb92
-rw-r--r--Library/Homebrew/utils/popen.rb14
-rw-r--r--Library/Homebrew/utils/ruby.sh13
-rw-r--r--Library/Homebrew/utils/shell.rb4
-rw-r--r--Library/Homebrew/utils/svn.rb4
-rw-r--r--Library/Homebrew/vendor/portable-ruby-version2
-rw-r--r--Library/Homebrew/version.rb214
282 files changed, 3876 insertions, 2765 deletions
diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml
index a2e3cc9c9..ed31de595 100644
--- a/Library/.rubocop.yml
+++ b/Library/.rubocop.yml
@@ -1,5 +1,5 @@
AllCops:
- TargetRubyVersion: 2.0
+ TargetRubyVersion: 2.3
Exclude:
- '**/Casks/**/*'
- '**/vendor/**/*'
@@ -123,7 +123,7 @@ Style/Tab:
Enabled: true
# dashes in filenames are typical
-Style/FileName:
+Naming/FileName:
Regex: !ruby/regexp /^[\w\@\-\+\.]+(\.rb)?$/
# falsely flags e.g. curl formatting arguments as format strings
@@ -193,8 +193,25 @@ Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: comma
# we have too many variables like sha256 where this harms readability
-Style/VariableNumber:
+Naming/VariableNumber:
Enabled: false
Style/WordArray:
MinSize: 4
+
+# we want to add this slowly and manually
+Style/FrozenStringLiteralComment:
+ Enabled: false
+
+# generally rescuing StandardError is fine
+Lint/RescueWithoutErrorClass:
+ Enabled: false
+
+# implicitly allow EOS as we use it everywhere
+Naming/HeredocDelimiterNaming:
+ Blacklist:
+ - END, EOD, EOF
+
+# we output how to use interpolated strings too often
+Lint/InterpolationCheck:
+ Enabled: false
diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml
index 26c944529..143468643 100644
--- a/Library/Homebrew/.rubocop.yml
+++ b/Library/Homebrew/.rubocop.yml
@@ -1,6 +1,5 @@
inherit_from:
- ../.rubocop.yml
- - .rubocop_todo.yml
AllCops:
Include:
@@ -26,12 +25,30 @@ Lint/NestedMethodDefinition:
Lint/ParenthesesAsGroupedExpression:
Enabled: true
+Metrics/BlockNesting:
+ Max: 5
+
+Metrics/ModuleLength:
+ Max: 360
+
Metrics/ParameterLists:
CountKeywordArgs: false
+# we won't change backward compatible method names
+Naming/MethodName:
+ Exclude:
+ - 'compat/**/*'
+
+# we won't change backward compatible predicate names
+Naming/PredicateName:
+ Exclude:
+ - 'compat/**/*'
+ NameWhitelist: is_32_bit?, is_64_bit?
+
Style/BlockDelimiters:
Exclude:
- '**/*_spec.rb'
+ - '**/shared_examples/**/*.rb'
# so many of these in formulae but none in here
Style/GuardClause:
@@ -40,14 +57,3 @@ Style/GuardClause:
# hash-rockets preferred for formulae, a: 1 preferred elsewhere
Style/HashSyntax:
EnforcedStyle: ruby19_no_mixed_keys
-
-# we won't change backward compatible method names
-Style/MethodName:
- Exclude:
- - 'compat/**/*'
-
-# we won't change backward compatible predicate names
-Style/PredicateName:
- Exclude:
- - 'compat/**/*'
- NameWhitelist: is_32_bit?, is_64_bit?
diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml
deleted file mode 100644
index 37518a5f0..000000000
--- a/Library/Homebrew/.rubocop_todo.yml
+++ /dev/null
@@ -1,145 +0,0 @@
-# This configuration was generated by
-# `rubocop --auto-gen-config --exclude-limit 100`
-# on 2017-01-27 21:44:55 +0000 using RuboCop version 0.47.1.
-# The point is for the user to remove these configuration records
-# one by one as the offenses are removed from the code base.
-# Note that changes in the inspected code, or installation of new
-# versions of RuboCop, may require this file to be generated again.
-
-# Offense count: 17
-Lint/HandleExceptions:
- Exclude:
- - 'cmd/install.rb'
- - 'cmd/reinstall.rb'
- - 'cmd/tap.rb'
- - 'cmd/update-report.rb'
- - 'cmd/upgrade.rb'
- - 'cmd/uses.rb'
- - 'descriptions.rb'
- - 'diagnostic.rb'
- - 'extend/ENV/super.rb'
- - 'extend/pathname.rb'
- - 'formula.rb'
- - 'formula_versions.rb'
- - 'test/ENV_test.rb'
-
-# Offense count: 3
-Lint/IneffectiveAccessModifier:
- Exclude:
- - 'formula.rb'
- - 'version.rb'
-
-# Offense count: 1
-Lint/Loop:
- Exclude:
- - 'patch.rb'
-
-# Offense count: 28
-Lint/RescueException:
- Exclude:
- - 'brew.rb'
- - 'build.rb'
- - 'cmd/fetch.rb'
- - 'cmd/reinstall.rb'
- - 'cmd/update-report.rb'
- - 'debrew.rb'
- - 'dev-cmd/pull.rb'
- - 'dev-cmd/test.rb'
- - 'formula.rb'
- - 'formula_installer.rb'
- - 'migrator.rb'
- - 'postinstall.rb'
- - 'readall.rb'
- - 'test.rb'
- - 'test/ENV_test.rb'
- - 'utils/fork.rb'
-
-# Offense count: 1
-Lint/ShadowedException:
- Exclude:
- - 'utils/fork.rb'
-
-# Offense count: 13
-# Configuration parameters: CountBlocks.
-Metrics/BlockNesting:
- Max: 5
-
-# Offense count: 19
-# Configuration parameters: CountComments.
-Metrics/ModuleLength:
- Max: 400
-
-# Offense count: 1
-# Configuration parameters: CountKeywordArgs.
-Metrics/ParameterLists:
- Max: 6
-
-# Offense count: 2
-Security/MarshalLoad:
- Exclude:
- - 'dependency.rb'
- - 'utils/fork.rb'
-
-# Offense count: 1
-Style/AccessorMethodName:
- Exclude:
- - 'extend/ENV/super.rb'
-
-# Offense count: 6
-Style/ClassVars:
- Exclude:
- - 'dev-cmd/audit.rb'
- - 'formula_installer.rb'
- - 'test/support/helper/fs_leak_logger.rb'
-
-# Offense count: 13
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: compact, expanded
-Style/EmptyMethod:
- Exclude:
- - 'debrew/irb.rb'
- - 'download_strategy.rb'
- - 'extend/ENV/super.rb'
- - 'formula.rb'
- - 'patch.rb'
-
-# Offense count: 13
-# Configuration parameters: AllowedVariables.
-Style/GlobalVars:
- Exclude:
- - 'diagnostic.rb'
- - 'utils.rb'
-
-# Offense count: 1
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: module_function, extend_self
-Style/ModuleFunction:
- Exclude:
- - 'os/mac/xcode.rb'
-
-# Offense count: 8
-Style/MultilineBlockChain:
- Exclude:
- - 'cmd/search.rb'
- - 'dev-cmd/aspell-dictionaries.rb'
- - 'dev-cmd/audit.rb'
- - 'dev-cmd/man.rb'
- - 'diagnostic.rb'
- - 'test/patching_test.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-Style/MutableConstant:
- Exclude:
- - 'dependency_collector.rb'
- - 'formulary.rb'
- - 'tab.rb'
- - 'tap.rb'
-
-# Offense count: 8
-Style/OpMethod:
- Exclude:
- - 'dependencies.rb'
- - 'install_renamed.rb'
- - 'options.rb'
diff --git a/Library/Homebrew/.simplecov b/Library/Homebrew/.simplecov
index 23e60faeb..e0d6d7601 100755
--- a/Library/Homebrew/.simplecov
+++ b/Library/Homebrew/.simplecov
@@ -11,11 +11,6 @@ SimpleCov.start do
# tests to be dropped. This causes random fluctuations in test coverage.
merge_timeout 86400
- add_filter "/Homebrew/compat/"
- add_filter "/Homebrew/dev-cmd/tests.rb"
- add_filter "/Homebrew/test/"
- add_filter "/Homebrew/vendor/"
-
if ENV["HOMEBREW_INTEGRATION_TEST"]
command_name "#{ENV["HOMEBREW_INTEGRATION_TEST"]} (#{$PROCESS_ID})"
@@ -33,22 +28,32 @@ SimpleCov.start do
end
else
command_name "#{command_name} (#{$PROCESS_ID})"
+
+ subdirs = Dir.chdir(SimpleCov.root) { Dir.glob("*") }
+ .reject { |d| d.end_with?(".rb") || ["test", "vendor"].include?(d) }
+ .map { |d| "#{d}/**/*.rb" }.join(",")
+
# Not using this during integration tests makes the tests 4x times faster
# without changing the coverage.
- track_files "#{SimpleCov.root}/**/*.rb"
+ track_files "#{SimpleCov.root}/{#{subdirs},*.rb}"
end
+ add_filter %r{^/compat/}
+ add_filter %r{^/dev-cmd/tests.rb$}
+ add_filter %r{^/test/}
+ add_filter %r{^/vendor/}
+
# Add groups and the proper project name to the output.
project_name "Homebrew"
- add_group "Cask", "/Homebrew/cask/"
- add_group "Commands", %w[/Homebrew/cmd/ /Homebrew/dev-cmd/]
- add_group "Extensions", "/Homebrew/extend/"
- add_group "OS", %w[/Homebrew/extend/os/ /Homebrew/os/]
- add_group "Requirements", "/Homebrew/requirements/"
- add_group "Scripts", %w[
- /Homebrew/brew.rb
- /Homebrew/build.rb
- /Homebrew/postinstall.rb
- /Homebrew/test.rb
+ add_group "Cask", %r{^/cask/}
+ add_group "Commands", [%r{/cmd/}, %r{^/dev-cmd/}]
+ add_group "Extensions", %r{^/extend/}
+ add_group "OS", [%r{^/extend/os/}, %r{^/os/}]
+ add_group "Requirements", %r{^/requirements/}
+ add_group "Scripts", [
+ %r{^/brew.rb$},
+ %r{^/build.rb$},
+ %r{^/postinstall.rb$},
+ %r{^/test.rb$},
]
end
diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb
index ec86bd794..86b40a79d 100644
--- a/Library/Homebrew/brew.rb
+++ b/Library/Homebrew/brew.rb
@@ -5,8 +5,12 @@ end
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
# check ruby version before requiring any modules.
-RUBY_TWO = RUBY_VERSION.split(".").first.to_i >= 2
-raise "Homebrew must be run under Ruby 2!" unless RUBY_TWO
+RUBY_VERSION_SPLIT = RUBY_VERSION.split "."
+RUBY_X = RUBY_VERSION_SPLIT[0].to_i
+RUBY_Y = RUBY_VERSION_SPLIT[1].to_i
+if RUBY_X < 2 || (RUBY_X == 2 && RUBY_Y < 3)
+ raise "Homebrew must be run under Ruby 2.3!"
+end
require "pathname"
HOMEBREW_LIBRARY_PATH = Pathname.new(__FILE__).realpath.parent
@@ -105,18 +109,16 @@ begin
possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) }
possible_tap = Tap.fetch(possible_tap.first) if possible_tap
- if possible_tap && !possible_tap.installed?
- brew_uid = HOMEBREW_BREW_FILE.stat.uid
- tap_commands = []
- if Process.uid.zero? && !brew_uid.zero?
- tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}]
- end
- tap_commands += %W[#{HOMEBREW_BREW_FILE} tap #{possible_tap}]
- safe_system(*tap_commands)
- exec HOMEBREW_BREW_FILE, cmd, *ARGV
- else
- odie "Unknown command: #{cmd}"
+ odie "Unknown command: #{cmd}" if !possible_tap || possible_tap.installed?
+
+ brew_uid = HOMEBREW_BREW_FILE.stat.uid
+ tap_commands = []
+ if Process.uid.zero? && !brew_uid.zero?
+ tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}]
end
+ tap_commands += %W[#{HOMEBREW_BREW_FILE} tap #{possible_tap}]
+ safe_system(*tap_commands)
+ exec HOMEBREW_BREW_FILE, cmd, *ARGV
end
rescue UsageError => e
require "cmd/help"
@@ -144,7 +146,7 @@ rescue MethodDeprecatedError => e
$stderr.puts " #{Formatter.url(e.issues_url)}"
end
exit 1
-rescue Exception => e
+rescue Exception => e # rubocop:disable Lint/RescueException
onoe e
if internal_cmd && defined?(OS::ISSUES_URL) &&
!ENV["HOMEBREW_NO_AUTO_UPDATE"]
diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh
index c40ce8bf7..b2859c927 100644
--- a/Library/Homebrew/brew.sh
+++ b/Library/Homebrew/brew.sh
@@ -23,7 +23,7 @@ HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbr
HOMEBREW_USER_AGENT_VERSION="$HOMEBREW_VERSION"
if [[ -z "$HOMEBREW_VERSION" ]]
then
- HOMEBREW_VERSION=">1.2.0 (no git repository)"
+ HOMEBREW_VERSION=">1.2.0 (shallow or no git repository)"
HOMEBREW_USER_AGENT_VERSION="1.X.Y"
fi
@@ -105,7 +105,14 @@ then
HOMEBREW_OS_USER_AGENT_VERSION="Mac OS X $HOMEBREW_MACOS_VERSION"
printf -v HOMEBREW_MACOS_VERSION_NUMERIC "%02d%02d%02d" ${HOMEBREW_MACOS_VERSION//./ }
- if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100900" &&
+ if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101000" ]]
+ then
+ HOMEBREW_SYSTEM_CURL_TOO_OLD="1"
+ fi
+
+ # The system Curl is too old for some modern HTTPS certificates on
+ # older macOS versions.
+ if [[ -n "$HOMEBREW_SYSTEM_CURL_TOO_OLD" &&
-x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]]
then
HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl"
diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb
index 8dd4fb245..836b360da 100644
--- a/Library/Homebrew/build.rb
+++ b/Library/Homebrew/build.rb
@@ -112,6 +112,10 @@ class Build
formula.extend(Debrew::Formula) if ARGV.debug?
formula.brew do |_formula, staging|
+ # For head builds, HOMEBREW_FORMULA_PREFIX should include the commit,
+ # which is not known until after the formula has been staged.
+ ENV["HOMEBREW_FORMULA_PREFIX"] = formula.prefix
+
staging.retain! if ARGV.keep_tmp?
formula.patch
@@ -186,7 +190,7 @@ begin
options = Options.create(ARGV.flags_only)
build = Build.new(formula, options)
build.install
-rescue Exception => e
+rescue Exception => e # rubocop:disable Lint/RescueException
Marshal.dump(e, error_pipe)
error_pipe.close
exit! 1
diff --git a/Library/Homebrew/cask/lib/hbc.rb b/Library/Homebrew/cask/lib/hbc.rb
index 780acedf5..01a085019 100644
--- a/Library/Homebrew/cask/lib/hbc.rb
+++ b/Library/Homebrew/cask/lib/hbc.rb
@@ -25,7 +25,6 @@ require "hbc/scopes"
require "hbc/staged"
require "hbc/system_command"
require "hbc/topological_hash"
-require "hbc/underscore_supporting_uri"
require "hbc/url"
require "hbc/utils"
require "hbc/verify"
diff --git a/Library/Homebrew/cask/lib/hbc/artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact.rb
index 074d15017..1cbe49cf2 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact.rb
@@ -25,47 +25,5 @@ require "hbc/artifact/zap"
module Hbc
module Artifact
- # NOTE: Order is important here!
- #
- # The `uninstall` stanza should be run first, as it may
- # depend on other artifacts still being installed.
- #
- # We want to extract nested containers before we
- # handle any other artifacts.
- #
- TYPES = [
- PreflightBlock,
- Uninstall,
- NestedContainer,
- Installer,
- App,
- Suite,
- Artifact, # generic 'artifact' stanza
- Colorpicker,
- Pkg,
- Prefpane,
- Qlplugin,
- Dictionary,
- Font,
- Service,
- StageOnly,
- Binary,
- InputMethod,
- InternetPlugin,
- AudioUnitPlugin,
- VstPlugin,
- Vst3Plugin,
- ScreenSaver,
- PostflightBlock,
- Zap,
- ].freeze
-
- def self.for_cask(cask, options = {})
- odebug "Determining which artifacts are present in Cask #{cask}"
-
- TYPES
- .select { |klass| klass.me?(cask) }
- .map { |klass| klass.new(cask, options) }
- end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb
new file mode 100644
index 000000000..f9f736662
--- /dev/null
+++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb
@@ -0,0 +1,109 @@
+module Hbc
+ module Artifact
+ class AbstractArtifact
+ include Comparable
+ extend Predicable
+
+ def self.english_name
+ @english_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1 \2')
+ end
+
+ def self.english_article
+ @english_article ||= (english_name =~ /^[aeiou]/i) ? "an" : "a"
+ end
+
+ def self.dsl_key
+ @dsl_key ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym
+ end
+
+ def self.dirmethod
+ @dirmethod ||= "#{dsl_key}dir".to_sym
+ end
+
+ def <=>(other)
+ return unless other.class < AbstractArtifact
+ return 0 if self.class == other.class
+
+ @@sort_order ||= [ # rubocop:disable Style/ClassVars
+ PreflightBlock,
+ # The `uninstall` stanza should be run first, as it may
+ # depend on other artifacts still being installed.
+ Uninstall,
+ # We want to extract nested containers before we
+ # handle any other artifacts.
+ NestedContainer,
+ Installer,
+ [
+ App,
+ Suite,
+ Artifact,
+ Colorpicker,
+ Prefpane,
+ Qlplugin,
+ Dictionary,
+ Font,
+ Service,
+ InputMethod,
+ InternetPlugin,
+ AudioUnitPlugin,
+ VstPlugin,
+ Vst3Plugin,
+ ScreenSaver,
+ ],
+ # `pkg` should be run before `binary`, so
+ # targets are created prior to linking.
+ Pkg,
+ Binary,
+ PostflightBlock,
+ Zap,
+ ].each_with_index.flat_map { |classes, i| [*classes].map { |c| [c, i] } }.to_h
+
+ (@@sort_order[self.class] <=> @@sort_order[other.class]).to_i
+ end
+
+ # TODO: this sort of logic would make more sense in dsl.rb, or a
+ # constructor called from dsl.rb, so long as that isn't slow.
+ def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil)
+ # TODO: when stanza names are harmonized with class names,
+ # stanza may not be needed as an explicit argument
+ description = key ? "#{stanza} #{key.inspect}" : stanza.to_s
+
+ # backward-compatible string value
+ arguments = { executable: arguments } if arguments.is_a?(String)
+
+ # key sanity
+ permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :print_stdout, :print_stderr]
+ unknown_keys = arguments.keys - permitted_keys
+ unless unknown_keys.empty?
+ opoo %Q{Unknown arguments to #{description} -- #{unknown_keys.inspect} (ignored). Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.}
+ end
+ arguments.select! { |k| permitted_keys.include?(k) }
+
+ # key warnings
+ override_keys = override_arguments.keys
+ ignored_keys = arguments.keys & override_keys
+ unless ignored_keys.empty?
+ onoe "Some arguments to #{description} will be ignored -- :#{unknown_keys.inspect} (overridden)."
+ end
+
+ # extract executable
+ executable = arguments.key?(:executable) ? arguments.delete(:executable) : nil
+
+ arguments = default_arguments.merge arguments
+ arguments.merge! override_arguments
+
+ [executable, arguments]
+ end
+
+ attr_reader :cask
+
+ def initialize(cask)
+ @cask = cask
+ end
+
+ def to_s
+ "#{summarize} (#{self.class.english_name})"
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb
index be3050acb..a3075ff40 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb
@@ -1,39 +1,45 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
module Hbc
module Artifact
- class AbstractFlightBlock < Base
- def self.artifact_dsl_key
+ class AbstractFlightBlock < AbstractArtifact
+ def self.dsl_key
super.to_s.sub(/_block$/, "").to_sym
end
- def self.uninstall_artifact_dsl_key
- artifact_dsl_key.to_s.prepend("uninstall_").to_sym
+ def self.uninstall_dsl_key
+ dsl_key.to_s.prepend("uninstall_").to_sym
end
- def self.class_for_dsl_key(dsl_key)
- Object.const_get("Hbc::DSL::#{dsl_key.to_s.split("_").collect(&:capitalize).join}")
- end
+ attr_reader :directives
- def self.me?(cask)
- cask.artifacts[artifact_dsl_key].any? ||
- cask.artifacts[uninstall_artifact_dsl_key].any?
+ def initialize(cask, **directives)
+ super(cask)
+ @directives = directives
end
- def install_phase
- abstract_phase(self.class.artifact_dsl_key)
+ def install_phase(**)
+ abstract_phase(self.class.dsl_key)
end
- def uninstall_phase
- abstract_phase(self.class.uninstall_artifact_dsl_key)
+ def uninstall_phase(**)
+ abstract_phase(self.class.uninstall_dsl_key)
end
private
+ def class_for_dsl_key(dsl_key)
+ namespace = self.class.name.to_s.sub(/::.*::.*$/, "")
+ self.class.const_get("#{namespace}::DSL::#{dsl_key.to_s.split("_").collect(&:capitalize).join}")
+ end
+
def abstract_phase(dsl_key)
- @cask.artifacts[dsl_key].each do |block|
- self.class.class_for_dsl_key(dsl_key).new(@cask).instance_eval(&block)
- end
+ return if (block = directives[dsl_key]).nil?
+ class_for_dsl_key(dsl_key).new(cask).instance_eval(&block)
+ end
+
+ def summarize
+ directives.keys.map(&:to_s).join(", ")
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb
index d92644150..3f63dae8f 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb
@@ -1,11 +1,11 @@
require "pathname"
require "timeout"
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
module Hbc
module Artifact
- class UninstallBase < Base
+ class AbstractUninstall < AbstractArtifact
ORDERED_DIRECTIVES = [
:early_script,
:launchctl,
@@ -20,26 +20,42 @@ module Hbc
:rmdir,
].freeze
- def dispatch_uninstall_directives
- directives_set = @cask.artifacts[stanza]
+ def self.from_args(cask, **directives)
+ new(cask, directives)
+ end
+
+ attr_reader :directives
+
+ def initialize(cask, directives)
+ super(cask)
+ directives[:signal] = [*directives[:signal]].flatten.each_slice(2).to_a
+ @directives = directives
+ end
+
+ def to_h
+ directives.to_h
+ end
+
+ def summarize
+ to_h.flat_map { |key, val| [*val].map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ")
+ end
+
+ private
+
+ def dispatch_uninstall_directives(**options)
ohai "Running #{stanza} process for #{@cask}; your password may be necessary"
- directives_set.each do |directives|
- warn_for_unknown_directives(directives)
- end
+ warn_for_unknown_directives(directives)
ORDERED_DIRECTIVES.each do |directive_sym|
- directives_set.select { |h| h.key?(directive_sym) }.each do |directives|
- args = directives[directive_sym]
- send("uninstall_#{directive_sym}", *(args.is_a?(Hash) ? [args] : args))
- end
+ next unless directives.key?(directive_sym)
+ args = directives[directive_sym]
+ send("uninstall_#{directive_sym}", *(args.is_a?(Hash) ? [args] : args), **options)
end
end
- private
-
def stanza
- self.class.artifact_dsl_key
+ self.class.dsl_key
end
def warn_for_unknown_directives(directives)
@@ -51,18 +67,18 @@ module Hbc
# Preserve prior functionality of script which runs first. Should rarely be needed.
# :early_script should not delete files, better defer that to :script.
# If Cask writers never need :early_script it may be removed in the future.
- def uninstall_early_script(directives)
- uninstall_script(directives, directive_name: :early_script)
+ def uninstall_early_script(directives, **options)
+ uninstall_script(directives, directive_name: :early_script, **options)
end
# :launchctl must come before :quit/:signal for cases where app would instantly re-launch
- def uninstall_launchctl(*services)
+ def uninstall_launchctl(*services, command: nil, **_)
services.each do |service|
ohai "Removing launchctl service #{service}"
[false, true].each do |with_sudo|
- plist_status = @command.run("/bin/launchctl", args: ["list", service], sudo: with_sudo, print_stderr: false).stdout
+ plist_status = command.run("/bin/launchctl", args: ["list", service], sudo: with_sudo, print_stderr: false).stdout
if plist_status =~ /^\{/
- @command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo)
+ command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo)
sleep 1
end
paths = ["/Library/LaunchAgents/#{service}.plist",
@@ -70,38 +86,38 @@ module Hbc
paths.each { |elt| elt.prepend(ENV["HOME"]) } unless with_sudo
paths = paths.map { |elt| Pathname(elt) }.select(&:exist?)
paths.each do |path|
- @command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo)
+ command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo)
end
# undocumented and untested: pass a path to uninstall :launchctl
next unless Pathname(service).exist?
- @command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: with_sudo)
- @command.run!("/bin/rm", args: ["-f", "--", service], sudo: with_sudo)
+ command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: with_sudo)
+ command.run!("/bin/rm", args: ["-f", "--", service], sudo: with_sudo)
sleep 1
end
end
end
- def running_processes(bundle_id)
- @command.run!("/bin/launchctl", args: ["list"]).stdout.lines
- .map { |line| line.chomp.split("\t") }
- .map { |pid, state, id| [pid.to_i, state.to_i, id] }
- .select do |fields|
- next if fields[0].zero?
- fields[2] =~ /^#{Regexp.escape(bundle_id)}($|\.\d+)/
- end
+ def running_processes(bundle_id, command: nil)
+ command.run!("/bin/launchctl", args: ["list"]).stdout.lines
+ .map { |line| line.chomp.split("\t") }
+ .map { |pid, state, id| [pid.to_i, state.to_i, id] }
+ .select do |fields|
+ next if fields[0].zero?
+ fields[2] =~ /^#{Regexp.escape(bundle_id)}($|\.\d+)/
+ end
end
# :quit/:signal must come before :kext so the kext will not be in use by a running process
- def uninstall_quit(*bundle_ids)
+ def uninstall_quit(*bundle_ids, command: nil, **_)
bundle_ids.each do |bundle_id|
ohai "Quitting application ID #{bundle_id}"
- next if running_processes(bundle_id).empty?
- @command.run!("/usr/bin/osascript", args: ["-e", %Q(tell application id "#{bundle_id}" to quit)], sudo: true)
+ next if running_processes(bundle_id, command: command).empty?
+ command.run!("/usr/bin/osascript", args: ["-e", %Q(tell application id "#{bundle_id}" to quit)], sudo: true)
begin
Timeout.timeout(3) do
Kernel.loop do
- break if running_processes(bundle_id).empty?
+ break if running_processes(bundle_id, command: command).empty?
end
end
rescue Timeout::Error
@@ -111,15 +127,15 @@ module Hbc
end
# :signal should come after :quit so it can be used as a backup when :quit fails
- def uninstall_signal(*signals)
- signals.flatten.each_slice(2) do |pair|
+ def uninstall_signal(*signals, command: nil, **_)
+ signals.each do |pair|
unless pair.size == 2
- raise CaskInvalidError.new(@cask, "Each #{stanza} :signal must consist of 2 elements.")
+ raise CaskInvalidError.new(cask, "Each #{stanza} :signal must consist of 2 elements.")
end
signal, bundle_id = pair
ohai "Signalling '#{signal}' to application ID '#{bundle_id}'"
- pids = running_processes(bundle_id).map(&:first)
+ pids = running_processes(bundle_id, command: command).map(&:first)
next unless pids.any?
# Note that unlike :quit, signals are sent from the current user (not
# upgraded to the superuser). This is a todo item for the future, but
@@ -133,10 +149,10 @@ module Hbc
end
end
- def uninstall_login_item(*login_items)
+ def uninstall_login_item(*login_items, command: nil, **_)
login_items.each do |name|
ohai "Removing login item #{name}"
- @command.run!("/usr/bin/osascript",
+ command.run!("/usr/bin/osascript",
args: ["-e", %Q(tell application "System Events" to delete every login item whose name is "#{name}")],
sudo: false)
sleep 1
@@ -144,23 +160,24 @@ module Hbc
end
# :kext should be unloaded before attempting to delete the relevant file
- def uninstall_kext(*kexts)
+ def uninstall_kext(*kexts, command: nil, **_)
kexts.each do |kext|
ohai "Unloading kernel extension #{kext}"
- is_loaded = @command.run!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: true).stdout
+ is_loaded = command.run!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: true).stdout
if is_loaded.length > 1
- @command.run!("/sbin/kextunload", args: ["-b", kext], sudo: true)
+ command.run!("/sbin/kextunload", args: ["-b", kext], sudo: true)
sleep 1
end
- @command.run!("/usr/sbin/kextfind", args: ["-b", kext], sudo: true).stdout.chomp.lines.each do |kext_path|
+ command.run!("/usr/sbin/kextfind", args: ["-b", kext], sudo: true).stdout.chomp.lines.each do |kext_path|
ohai "Removing kernel extension #{kext_path}"
- @command.run!("/bin/rm", args: ["-rf", kext_path], sudo: true)
+ command.run!("/bin/rm", args: ["-rf", kext_path], sudo: true)
end
end
end
# :script must come before :pkgutil, :delete, or :trash so that the script file is not already deleted
- def uninstall_script(directives, directive_name: :script)
+ def uninstall_script(directives, directive_name: :script, force: false, command: nil, **_)
+ # TODO: Create a common `Script` class to run this and Artifact::Installer.
executable, script_arguments = self.class.read_script_arguments(directives,
"uninstall",
{ must_succeed: true, sudo: false },
@@ -168,25 +185,25 @@ module Hbc
directive_name)
ohai "Running uninstall script #{executable}"
- raise CaskInvalidError.new(@cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil?
- executable_path = @cask.staged_path.join(executable)
+ raise CaskInvalidError.new(cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil?
+ executable_path = cask.staged_path.join(executable)
unless executable_path.exist?
message = "uninstall script #{executable} does not exist"
- raise CaskError, "#{message}." unless force?
+ raise CaskError, "#{message}." unless force
opoo "#{message}, skipping."
return
end
- @command.run("/bin/chmod", args: ["--", "+x", executable_path])
- @command.run(executable_path, script_arguments)
+ command.run("/bin/chmod", args: ["--", "+x", executable_path])
+ command.run(executable_path, script_arguments)
sleep 1
end
- def uninstall_pkgutil(*pkgs)
+ def uninstall_pkgutil(*pkgs, command: nil, **_)
ohai "Uninstalling packages:"
pkgs.each do |regex|
- Hbc::Pkg.all_matching(regex, @command).each do |pkg|
+ Hbc::Pkg.all_matching(regex, command).each do |pkg|
puts pkg.package_id
pkg.uninstall
end
@@ -215,28 +232,28 @@ module Hbc
end
end
- def uninstall_delete(*paths)
+ def uninstall_delete(*paths, command: nil, **_)
return if paths.empty?
ohai "Removing files:"
each_resolved_path(:delete, paths) do |path, resolved_paths|
puts path
- @command.run!("/usr/bin/xargs", args: ["-0", "--", "/bin/rm", "-r", "-f", "--"], input: resolved_paths.join("\0"), sudo: true)
+ command.run!("/usr/bin/xargs", args: ["-0", "--", "/bin/rm", "-r", "-f", "--"], input: resolved_paths.join("\0"), sudo: true)
end
end
- def uninstall_trash(*paths)
+ def uninstall_trash(*paths, **options)
return if paths.empty?
resolved_paths = each_resolved_path(:trash, paths).to_a
ohai "Trashing files:"
puts resolved_paths.map(&:first)
- trash_paths(*resolved_paths.flat_map(&:last))
+ trash_paths(*resolved_paths.flat_map(&:last), **options)
end
- def trash_paths(*paths)
- @command.run!("/usr/bin/osascript", args: ["-e", <<-'EOS'.undent, *paths])
+ def trash_paths(*paths, command: nil, **_)
+ result = command.run!("/usr/bin/osascript", args: ["-e", <<-'EOS'.undent, *paths])
on run argv
repeat with i from 1 to (count argv)
set item i of argv to (item i of argv as POSIX file)
@@ -250,7 +267,7 @@ module Hbc
set trashedItem to POSIX path of (item i of trashedItems as string)
set output to output & trashedItem
if i < count trashedItems then
- set output to output & (do shell script "printf \"\\0\"")
+ set output to output & character id 0
end if
end repeat
@@ -258,9 +275,12 @@ module Hbc
end tell
end run
EOS
+
+ # Remove AppleScript's automatic newline.
+ result.tap { |r| r.stdout.sub!(/\n$/, "") }
end
- def uninstall_rmdir(*directories)
+ def uninstall_rmdir(*directories, command: nil, **_)
return if directories.empty?
ohai "Removing directories if empty:"
@@ -268,10 +288,10 @@ module Hbc
puts path
resolved_paths.select(&:directory?).each do |resolved_path|
if (ds_store = resolved_path.join(".DS_Store")).exist?
- @command.run!("/bin/rm", args: ["-f", "--", ds_store], sudo: true, print_stderr: false)
+ command.run!("/bin/rm", args: ["-f", "--", ds_store], sudo: true, print_stderr: false)
end
- @command.run("/bin/rmdir", args: ["--", resolved_path], sudo: true, print_stderr: false)
+ command.run("/bin/rmdir", args: ["--", resolved_path], sudo: true, print_stderr: false)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb
index b42db877d..0f37afade 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb
@@ -5,21 +5,32 @@ require "hbc/utils/hash_validator"
module Hbc
module Artifact
class Artifact < Moved
- def self.artifact_english_name
+ def self.english_name
"Generic Artifact"
end
- def self.artifact_dirmethod
- :appdir
- end
+ def self.from_args(cask, *args)
+ source_string, target_hash = args
+
+ if source_string.nil?
+ raise CaskInvalidError.new(cask.token, "no source given for #{english_name}")
+ end
+
+ unless target_hash.is_a?(Hash)
+ raise CaskInvalidError.new(cask.token, "target required for #{english_name} '#{source_string}'")
+ end
- def load_specification(artifact_spec)
- source_string, target_hash = artifact_spec
- raise CaskInvalidError.new(@cask.token, "no source given for artifact") if source_string.nil?
- @source = @cask.staged_path.join(source_string)
- raise CaskInvalidError.new(@cask.token, "target required for generic artifact #{source_string}") unless target_hash.is_a?(Hash)
target_hash.extend(HashValidator).assert_valid_keys(:target)
- @target = Pathname.new(target_hash[:target])
+
+ new(cask, source_string, **target_hash)
+ end
+
+ def self.resolve_target(target)
+ Pathname(target)
+ end
+
+ def initialize(cask, source, target: nil)
+ super(cask, source, target: target)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/base.rb b/Library/Homebrew/cask/lib/hbc/artifact/base.rb
deleted file mode 100644
index ae15552a4..000000000
--- a/Library/Homebrew/cask/lib/hbc/artifact/base.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-module Hbc
- module Artifact
- class Base
- extend Predicable
-
- def self.artifact_name
- @artifact_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase
- end
-
- def self.artifact_english_name
- @artifact_english_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1 \2')
- end
-
- def self.artifact_english_article
- @artifact_english_article ||= (artifact_english_name =~ /^[aeiou]/i) ? "an" : "a"
- end
-
- def self.artifact_dsl_key
- @artifact_dsl_key ||= artifact_name.to_sym
- end
-
- def self.artifact_dirmethod
- @artifact_dirmethod ||= "#{artifact_name}dir".to_sym
- end
-
- def self.me?(cask)
- cask.artifacts[artifact_dsl_key].any?
- end
-
- attr_reader :force
-
- # TODO: this sort of logic would make more sense in dsl.rb, or a
- # constructor called from dsl.rb, so long as that isn't slow.
- def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil)
- # TODO: when stanza names are harmonized with class names,
- # stanza may not be needed as an explicit argument
- description = key ? "#{stanza} #{key.inspect}" : stanza.to_s
-
- # backward-compatible string value
- arguments = { executable: arguments } if arguments.is_a?(String)
-
- # key sanity
- permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :print_stdout, :print_stderr]
- unknown_keys = arguments.keys - permitted_keys
- unless unknown_keys.empty?
- opoo %Q{Unknown arguments to #{description} -- #{unknown_keys.inspect} (ignored). Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.}
- end
- arguments.select! { |k| permitted_keys.include?(k) }
-
- # key warnings
- override_keys = override_arguments.keys
- ignored_keys = arguments.keys & override_keys
- unless ignored_keys.empty?
- onoe "Some arguments to #{description} will be ignored -- :#{unknown_keys.inspect} (overridden)."
- end
-
- # extract executable
- executable = arguments.key?(:executable) ? arguments.delete(:executable) : nil
-
- arguments = default_arguments.merge arguments
- arguments.merge! override_arguments
-
- [executable, arguments]
- end
-
- def summary
- {}
- end
-
- attr_predicate :force?, :verbose?
-
- def initialize(cask, command: SystemCommand, force: false, verbose: false)
- @cask = cask
- @command = command
- @force = force
- @verbose = verbose
- end
- end
- end
-end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/binary.rb b/Library/Homebrew/cask/lib/hbc/artifact/binary.rb
index 7178c2af6..68f4b074d 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/binary.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/binary.rb
@@ -3,13 +3,13 @@ require "hbc/artifact/symlinked"
module Hbc
module Artifact
class Binary < Symlinked
- def link
- super
+ def link(command: nil, **options)
+ super(command: command, **options)
return if source.executable?
if source.writable?
FileUtils.chmod "+x", source
else
- @command.run!("/bin/chmod", args: ["+x", source], sudo: true)
+ command.run!("/bin/chmod", args: ["+x", source], sudo: true)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb
index be857696e..588bcabd5 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb
@@ -1,29 +1,82 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
module Hbc
module Artifact
- class Installer < Base
- def install_phase
- @cask.artifacts[self.class.artifact_dsl_key].each do |artifact|
- if artifact.manual
- puts <<-EOS.undent
- To complete the installation of Cask #{@cask}, you must also
- run the installer at
-
- '#{@cask.staged_path.join(artifact.manual)}'
-
- EOS
- else
- executable, script_arguments = self.class.read_script_arguments(artifact.script,
- self.class.artifact_dsl_key.to_s,
- { must_succeed: true, sudo: false },
- print_stdout: true)
- ohai "Running #{self.class.artifact_dsl_key} script #{executable}"
- raise CaskInvalidError.new(@cask, "#{self.class.artifact_dsl_key} missing executable") if executable.nil?
- executable_path = @cask.staged_path.join(executable)
- @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path)
- @command.run(executable_path, script_arguments)
+ class Installer < AbstractArtifact
+ VALID_KEYS = Set.new [
+ :manual,
+ :script,
+ ]
+
+ module ManualInstaller
+ def install_phase(**)
+ puts <<-EOS.undent
+ To complete the installation of Cask #{cask}, you must also
+ run the installer at
+
+ '#{path}'
+ EOS
+ end
+ end
+
+ module ScriptInstaller
+ def install_phase(command: nil, **_)
+ ohai "Running #{self.class.dsl_key} script '#{path.relative_path_from(cask.staged_path)}'"
+ FileUtils.chmod "+x", path unless path.executable?
+ command.run(path, **args)
+ end
+ end
+
+ def self.from_args(cask, **args)
+ raise CaskInvalidError.new(cask, "'installer' stanza requires an argument.") if args.empty?
+
+ if args.key?(:script) && !args[:script].respond_to?(:key?)
+ if args.key?(:executable)
+ raise CaskInvalidError.new(cask, "'installer' stanza gave arguments for both :script and :executable.")
end
+
+ args[:executable] = args[:script]
+ args.delete(:script)
+ args = { script: args }
+ end
+
+ unless args.keys.count == 1
+ raise CaskInvalidError.new(cask, "invalid 'installer' stanza: Only one of #{VALID_KEYS.inspect} is permitted.")
+ end
+
+ args.extend(HashValidator).assert_valid_keys(*VALID_KEYS)
+ new(cask, **args)
+ end
+
+ attr_reader :path, :args
+
+ def initialize(cask, **args)
+ super(cask)
+
+ if args.key?(:manual)
+ @path = cask.staged_path.join(args[:manual])
+ @args = []
+ extend(ManualInstaller)
+ return
+ end
+
+ path, @args = self.class.read_script_arguments(
+ args[:script], self.class.dsl_key.to_s, { must_succeed: true, sudo: false }, print_stdout: true
+ )
+ raise CaskInvalidError.new(cask, "#{self.class.dsl_key} missing executable") if path.nil?
+
+ path = Pathname(path)
+ @path = path.absolute? ? path : cask.staged_path.join(path)
+ extend(ScriptInstaller)
+ end
+
+ def summarize
+ path.relative_path_from(cask.staged_path).to_s
+ end
+
+ def to_h
+ { path: path.relative_path_from(cask.staged_path).to_s }.tap do |h|
+ h[:args] = args unless is_a?(ManualInstaller)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
index 3fe969c0c..ba1c8e907 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
@@ -4,63 +4,61 @@ module Hbc
module Artifact
class Moved < Relocated
def self.english_description
- "#{artifact_english_name}s"
+ "#{english_name}s"
end
- def install_phase
- each_artifact(&method(:move))
+ def install_phase(**options)
+ move(**options)
end
- def uninstall_phase
- each_artifact(&method(:delete))
+ def uninstall_phase(**options)
+ delete(**options)
+ end
+
+ def summarize_installed
+ if target.exist?
+ "#{printable_target} (#{target.abv})"
+ else
+ Formatter.error(printable_target, label: "Missing #{self.class.english_name}")
+ end
end
private
- def move
+ def move(force: false, command: nil, **options)
if Utils.path_occupied?(target)
- message = "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'"
- raise CaskError, "#{message}." unless force?
+ message = "It seems there is already #{self.class.english_article} #{self.class.english_name} at '#{target}'"
+ raise CaskError, "#{message}." unless force
opoo "#{message}; overwriting."
- delete
+ delete(force: force, command: command, **options)
end
unless source.exist?
- raise CaskError, "It seems the #{self.class.artifact_english_name} source '#{source}' is not there."
+ raise CaskError, "It seems the #{self.class.english_name} source '#{source}' is not there."
end
- ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'."
+ ohai "Moving #{self.class.english_name} '#{source.basename}' to '#{target}'."
target.dirname.mkpath
if target.parent.writable?
FileUtils.move(source, target)
else
- SystemCommand.run("/bin/mv", args: [source, target], sudo: true)
+ command.run("/bin/mv", args: [source, target], sudo: true)
end
- add_altname_metadata target, source.basename.to_s
+ add_altname_metadata(target, source.basename, command: command)
end
- def delete
- ohai "Removing #{self.class.artifact_english_name} '#{target}'."
- raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}." if MacOS.undeletable?(target)
+ def delete(force: false, command: nil, **_)
+ ohai "Removing #{self.class.english_name} '#{target}'."
+ raise CaskError, "Cannot remove undeletable #{self.class.english_name}." if MacOS.undeletable?(target)
return unless Utils.path_occupied?(target)
if target.parent.writable? && !force
target.rmtree
else
- Utils.gain_permissions_remove(target, command: @command)
- end
- end
-
- def summarize_artifact(artifact_spec)
- load_specification artifact_spec
-
- if target.exist?
- "#{printable_target} (#{target.abv})"
- else
- Formatter.error(printable_target, label: "Missing #{self.class.artifact_english_name}")
+ Utils.gain_permissions_remove(target, command: command)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb
index 84253ea30..c9fd3dc27 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb
@@ -1,23 +1,35 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
module Hbc
module Artifact
- class NestedContainer < Base
- def install_phase
- @cask.artifacts[:nested_container].each { |container| extract(container) }
+ class NestedContainer < AbstractArtifact
+ attr_reader :path
+
+ def initialize(cask, path)
+ super(cask)
+ @path = cask.staged_path.join(path)
+ end
+
+ def install_phase(**options)
+ extract(**options)
+ end
+
+ private
+
+ def summarize
+ path.relative_path_from(cask.staged_path).to_s
end
- def extract(container_relative_path)
- source = @cask.staged_path.join(container_relative_path)
- container = Container.for_path(source, @command)
+ def extract(command: nil, verbose: nil, **_)
+ container = Container.for_path(path, command)
unless container
raise CaskError, "Aw dang, could not identify nested container at '#{source}'"
end
- ohai "Extracting nested container #{source.basename}"
- container.new(@cask, source, @command, verbose: verbose?).extract
- FileUtils.remove_entry_secure(source)
+ ohai "Extracting nested container #{path.relative_path_from(cask.staged_path)}"
+ container.new(cask, path, command, verbose: verbose).extract
+ FileUtils.remove_entry_secure(path)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb
index be0a6be71..b4bdf3de6 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb
@@ -1,4 +1,4 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
require "hbc/utils/hash_validator"
@@ -6,62 +6,61 @@ require "vendor/plist/plist"
module Hbc
module Artifact
- class Pkg < Base
+ class Pkg < AbstractArtifact
attr_reader :pkg_relative_path
- def self.artifact_dsl_key
- :pkg
+ def self.from_args(cask, path, **stanza_options)
+ stanza_options.extend(HashValidator).assert_valid_keys(
+ :allow_untrusted, :choices
+ )
+ new(cask, path, **stanza_options)
end
- def load_pkg_description(pkg_description)
- @pkg_relative_path = pkg_description.shift
- @pkg_install_opts = pkg_description.shift
- begin
- if @pkg_install_opts.respond_to?(:keys)
- @pkg_install_opts.extend(HashValidator).assert_valid_keys(:allow_untrusted, :choices)
- elsif @pkg_install_opts
- raise
- end
- raise if pkg_description.nil?
- rescue StandardError
- raise CaskInvalidError.new(@cask, "Bad pkg stanza")
- end
+ attr_reader :path, :stanza_options
+
+ def initialize(cask, path, **stanza_options)
+ super(cask)
+ @path = cask.staged_path.join(path)
+ @stanza_options = stanza_options
end
- def pkg_install_opts(opt)
- @pkg_install_opts[opt] if @pkg_install_opts.respond_to?(:keys)
+ def summarize
+ path.relative_path_from(cask.staged_path).to_s
end
- def install_phase
- @cask.artifacts[:pkg].each { |pkg_description| run_installer(pkg_description) }
+ def install_phase(**options)
+ run_installer(**options)
end
- def run_installer(pkg_description)
- load_pkg_description pkg_description
- ohai "Running installer for #{@cask}; your password may be necessary."
+ private
+
+ def run_installer(command: nil, verbose: false, **_options)
+ ohai "Running installer for #{cask}; your password may be necessary."
ohai "Package installers may write to any location; options such as --appdir are ignored."
- source = @cask.staged_path.join(pkg_relative_path)
- unless source.exist?
- raise CaskError, "pkg source file not found: '#{source}'"
+ unless path.exist?
+ raise CaskError, "pkg source file not found: '#{path.relative_path_from(cask.staged_path)}'"
end
args = [
- "-pkg", source,
+ "-pkg", path,
"-target", "/"
]
- args << "-verboseR" if verbose?
- args << "-allowUntrusted" if pkg_install_opts :allow_untrusted
+ args << "-verboseR" if verbose
+ if stanza_options.fetch(:allow_untrusted, false)
+ args << "-allowUntrusted"
+ end
with_choices_file do |choices_path|
args << "-applyChoiceChangesXML" << choices_path if choices_path
- @command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true)
+ command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true)
end
end
def with_choices_file
- return yield nil unless pkg_install_opts(:choices)
+ choices = stanza_options.fetch(:choices, {})
+ return yield nil if choices.empty?
Tempfile.open(["choices", ".xml"]) do |file|
begin
- file.write Plist::Emit.dump(pkg_install_opts(:choices))
+ file.write Plist::Emit.dump(choices)
file.close
yield file.path
ensure
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb b/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb
index a44f8ae3a..87f120934 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb
@@ -3,7 +3,7 @@ require "hbc/artifact/moved"
module Hbc
module Artifact
class Prefpane < Moved
- def self.artifact_english_name
+ def self.english_name
"Preference Pane"
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb
index ee41de2fe..298714d89 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb
@@ -3,22 +3,24 @@ require "hbc/artifact/moved"
module Hbc
module Artifact
class Qlplugin < Moved
- def self.artifact_english_name
+ def self.english_name
"QuickLook Plugin"
end
- def install_phase
- super
- reload_quicklook
+ def install_phase(**options)
+ super(**options)
+ reload_quicklook(**options)
end
- def uninstall_phase
- super
- reload_quicklook
+ def uninstall_phase(**options)
+ super(**options)
+ reload_quicklook(**options)
end
- def reload_quicklook
- @command.run!("/usr/bin/qlmanage", args: ["-r"])
+ private
+
+ def reload_quicklook(command: nil, **_)
+ command.run!("/usr/bin/qlmanage", args: ["-r"])
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb
index 4dba46c9d..540699630 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb
@@ -1,65 +1,79 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
require "hbc/utils/hash_validator"
module Hbc
module Artifact
- class Relocated < Base
- def summary
- {
- english_description: self.class.english_description,
- contents: @cask.artifacts[self.class.artifact_dsl_key].map(&method(:summarize_artifact)).compact,
- }
+ class Relocated < AbstractArtifact
+ def self.from_args(cask, *args)
+ source_string, target_hash = args
+
+ if target_hash
+ raise CaskInvalidError unless target_hash.respond_to?(:keys)
+ target_hash.extend(HashValidator).assert_valid_keys(:target)
+ end
+
+ target_hash ||= {}
+
+ new(cask, source_string, **target_hash)
+ end
+
+ def self.resolve_target(target)
+ Hbc.public_send(dirmethod).join(target)
end
attr_reader :source, :target
- def printable_target
- target.to_s.sub(/^#{ENV['HOME']}(#{File::SEPARATOR}|$)/, "~/")
+ def initialize(cask, source, target: nil)
+ super(cask)
+
+ @source_string = source.to_s
+ @target_string = target.to_s
+ source = cask.staged_path.join(source)
+ @source = source
+ target ||= source.basename
+ @target = self.class.resolve_target(target)
end
+ def to_a
+ [@source_string].tap do |ary|
+ ary << { target: @target_string } unless @target_string.empty?
+ end
+ end
+
+ def summarize
+ target_string = @target_string.empty? ? "" : " -> #{@target_string}"
+ "#{@source_string}#{target_string}"
+ end
+
+ private
+
ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames".freeze
# Try to make the asset searchable under the target name. Spotlight
# respects this attribute for many filetypes, but ignores it for App
# bundles. Alfred 2.2 respects it even for App bundles.
- def add_altname_metadata(file, altname)
- return if altname.casecmp(file.basename).zero?
+ def add_altname_metadata(file, altname, command: nil)
+ return if altname.to_s.casecmp(file.basename.to_s).zero?
odebug "Adding #{ALT_NAME_ATTRIBUTE} metadata"
- altnames = @command.run("/usr/bin/xattr",
- args: ["-p", ALT_NAME_ATTRIBUTE, file.to_s],
+ altnames = command.run("/usr/bin/xattr",
+ args: ["-p", ALT_NAME_ATTRIBUTE, file],
print_stderr: false).stdout.sub(/\A\((.*)\)\Z/, '\1')
odebug "Existing metadata is: '#{altnames}'"
altnames.concat(", ") unless altnames.empty?
altnames.concat(%Q("#{altname}"))
altnames = "(#{altnames})"
- # Some packges are shipped as u=rx (e.g. Bitcoin Core)
- @command.run!("/bin/chmod", args: ["--", "u+rw", file, file.realpath])
+ # Some packages are shipped as u=rx (e.g. Bitcoin Core)
+ command.run!("/bin/chmod", args: ["--", "u+rw", file, file.realpath])
- @command.run!("/usr/bin/xattr",
+ command.run!("/usr/bin/xattr",
args: ["-w", ALT_NAME_ATTRIBUTE, altnames, file],
print_stderr: false)
end
- def each_artifact
- @cask.artifacts[self.class.artifact_dsl_key].each do |artifact|
- load_specification(artifact)
- yield
- end
- end
-
- def load_specification(artifact_spec)
- source_string, target_hash = artifact_spec
- raise CaskInvalidError if source_string.nil?
- @source = @cask.staged_path.join(source_string)
- if target_hash
- raise CaskInvalidError unless target_hash.respond_to?(:keys)
- target_hash.extend(HashValidator).assert_valid_keys(:target)
- @target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target])
- else
- @target = Hbc.send(self.class.artifact_dirmethod).join(source.basename)
- end
+ def printable_target
+ target.to_s.sub(/^#{ENV['HOME']}(#{File::SEPARATOR}|$)/, "~/")
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb b/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb
index 1122c1d02..8c32a52d0 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb
@@ -1,10 +1,22 @@
-require "hbc/artifact/base"
+require "hbc/artifact/abstract_artifact"
module Hbc
module Artifact
- class StageOnly < Base
- def self.artifact_dsl_key
- :stage_only
+ class StageOnly < AbstractArtifact
+ def self.from_args(cask, *args)
+ if args != [true]
+ raise CaskInvalidError.new(cask.token, "'stage_only' takes only a single argument: true")
+ end
+
+ new(cask)
+ end
+
+ def initialize(cask)
+ super(cask)
+ end
+
+ def to_a
+ [true]
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/suite.rb b/Library/Homebrew/cask/lib/hbc/artifact/suite.rb
index 35251f70c..59ae58cf1 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/suite.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/suite.rb
@@ -3,11 +3,11 @@ require "hbc/artifact/moved"
module Hbc
module Artifact
class Suite < Moved
- def self.artifact_english_name
+ def self.english_name
"App Suite"
end
- def self.artifact_dirmethod
+ def self.dirmethod
:appdir
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb b/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb
index 16715fe81..3726ebb5c 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb
@@ -8,58 +8,56 @@ module Hbc
end
def self.english_description
- "#{artifact_english_name} #{link_type_english_name}s"
+ "#{english_name} #{link_type_english_name}s"
end
- def install_phase
- each_artifact(&method(:link))
+ def install_phase(**options)
+ link(**options)
end
- def uninstall_phase
- each_artifact(&method(:unlink))
+ def uninstall_phase(**options)
+ unlink(**options)
+ end
+
+ def summarize_installed
+ if target.symlink? && target.exist? && target.readlink.exist?
+ "#{printable_target} -> #{target.readlink} (#{target.readlink.abv})"
+ else
+ string = if target.symlink?
+ "#{printable_target} -> #{target.readlink}"
+ else
+ printable_target
+ end
+
+ Formatter.error(string, label: "Broken Link")
+ end
end
private
- def link
+ def link(**options)
unless source.exist?
raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} source '#{source}' is not there."
end
if target.exist? && !target.symlink?
- raise CaskError, "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking."
+ raise CaskError, "It seems there is already #{self.class.english_article} #{self.class.english_name} at '#{target}'; not linking."
end
- ohai "Linking #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'."
- create_filesystem_link(source, target)
+ ohai "Linking #{self.class.english_name} '#{source.basename}' to '#{target}'."
+ create_filesystem_link(**options)
end
- def unlink
+ def unlink(**)
return unless target.symlink?
- ohai "Unlinking #{self.class.artifact_english_name} '#{target}'."
+ ohai "Unlinking #{self.class.english_name} '#{target}'."
target.delete
end
- def create_filesystem_link(source, target)
+ def create_filesystem_link(command: nil, **_)
target.dirname.mkpath
- @command.run!("/bin/ln", args: ["-h", "-f", "-s", "--", source, target])
- add_altname_metadata source, target.basename.to_s
- end
-
- def summarize_artifact(artifact_spec)
- load_specification artifact_spec
-
- if target.symlink? && target.exist? && target.readlink.exist?
- "#{printable_target} -> #{target.readlink} (#{target.readlink.abv})"
- else
- string = if target.symlink?
- "#{printable_target} -> #{target.readlink}"
- else
- printable_target
- end
-
- Formatter.error(string, label: "Broken Link")
- end
+ command.run!("/bin/ln", args: ["-h", "-f", "-s", "--", source, target])
+ add_altname_metadata(source, target.basename, command: command)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb b/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb
index 5a3dc098d..2bbf82862 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb
@@ -1,10 +1,10 @@
-require "hbc/artifact/uninstall_base"
+require "hbc/artifact/abstract_uninstall"
module Hbc
module Artifact
- class Uninstall < UninstallBase
- def uninstall_phase
- dispatch_uninstall_directives
+ class Uninstall < AbstractUninstall
+ def uninstall_phase(**options)
+ dispatch_uninstall_directives(**options)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/zap.rb b/Library/Homebrew/cask/lib/hbc/artifact/zap.rb
index cdfe2531d..31ff54d20 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/zap.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/zap.rb
@@ -1,10 +1,10 @@
-require "hbc/artifact/uninstall_base"
+require "hbc/artifact/abstract_uninstall"
module Hbc
module Artifact
- class Zap < UninstallBase
- def zap_phase
- dispatch_uninstall_directives
+ class Zap < AbstractUninstall
+ def zap_phase(**options)
+ dispatch_uninstall_directives(**options)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/audit.rb b/Library/Homebrew/cask/lib/hbc/audit.rb
index cee1fe807..bd25477ac 100644
--- a/Library/Homebrew/cask/lib/hbc/audit.rb
+++ b/Library/Homebrew/cask/lib/hbc/audit.rb
@@ -70,12 +70,16 @@ module Hbc
previous_cask_contents = Git.last_revision_of_file(tap.path, @cask.sourcefile_path, before_commit: commit_range)
return if previous_cask_contents.empty?
- previous_cask = CaskLoader.load_from_string(previous_cask_contents)
+ begin
+ previous_cask = CaskLoader.load(previous_cask_contents)
- return unless previous_cask.version == cask.version
- return if previous_cask.sha256 == cask.sha256
+ return unless previous_cask.version == cask.version
+ return if previous_cask.sha256 == cask.sha256
- add_error "only sha256 changed (see: https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/sha256.md)"
+ add_error "only sha256 changed (see: https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/sha256.md)"
+ rescue CaskError => e
+ add_warning "Skipped version and checksum comparison. Reading previous version failed: #{e}"
+ end
end
def check_version
@@ -143,7 +147,15 @@ module Hbc
def check_appcast_http_code
odebug "Verifying appcast returns 200 HTTP response code"
- result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
+
+ curl_executable, *args = curl_args(
+ "--compressed", "--location", "--fail",
+ "--write-out", "%{http_code}",
+ "--output", "/dev/null",
+ cask.appcast,
+ user_agent: :fake
+ )
+ result = @command.run(curl_executable, args: args, print_stderr: false)
if result.success?
http_code = result.stdout.chomp
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
@@ -206,12 +218,10 @@ module Hbc
end
def check_generic_artifacts
- cask.artifacts[:artifact].each do |source, target_hash|
- unless target_hash.is_a?(Hash) && target_hash[:target]
- add_error "target required for generic artifact #{source}"
- next
+ cask.artifacts.select { |a| a.is_a?(Hbc::Artifact::Artifact) }.each do |artifact|
+ unless artifact.target.absolute?
+ add_error "target must be absolute path for #{artifact.class.english_name} #{artifact.source}"
end
- add_error "target must be absolute path for generic artifact #{source}" unless Pathname.new(target_hash[:target]).absolute?
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/auditor.rb b/Library/Homebrew/cask/lib/hbc/auditor.rb
index 48f36a54d..231c005f9 100644
--- a/Library/Homebrew/cask/lib/hbc/auditor.rb
+++ b/Library/Homebrew/cask/lib/hbc/auditor.rb
@@ -43,7 +43,7 @@ module Hbc
def audit_languages(languages)
ohai "Auditing language: #{languages.map { |lang| "'#{lang}'" }.join(", ")}"
MacOS.instance_variable_set(:@languages, languages)
- audit_cask_instance(CaskLoader.load_from_file(cask.sourcefile_path))
+ audit_cask_instance(CaskLoader.load(cask.sourcefile_path))
ensure
CLI::Cleanup.run(cask.token) if audit_download?
end
diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb
index 6d89a997c..72a23066f 100644
--- a/Library/Homebrew/cask/lib/hbc/cask.rb
+++ b/Library/Homebrew/cask/lib/hbc/cask.rb
@@ -17,7 +17,7 @@ module Hbc
@token = token
@sourcefile_path = sourcefile_path
@tap = tap
- @dsl = DSL.new(@token)
+ @dsl = DSL.new(self)
return unless block_given?
@dsl.instance_eval(&block)
@dsl.language_eval
@@ -41,6 +41,14 @@ module Hbc
.reverse
end
+ def full_name
+ if @tap.nil? || @tap == Hbc.default_tap
+ token
+ else
+ "#{@tap}/#{token}"
+ end
+ end
+
def installed?
!versions.empty?
end
diff --git a/Library/Homebrew/cask/lib/hbc/cask_loader.rb b/Library/Homebrew/cask/lib/hbc/cask_loader.rb
index 500314671..08d457643 100644
--- a/Library/Homebrew/cask/lib/hbc/cask_loader.rb
+++ b/Library/Homebrew/cask/lib/hbc/cask_loader.rb
@@ -3,6 +3,18 @@ module Hbc
class FromContentLoader
attr_reader :content
+ def self.can_load?(ref)
+ return false unless ref.respond_to?(:to_str)
+ content = ref.to_str
+
+ token = /(?:"[^"]*"|'[^']*')/
+ curly = /\(\s*#{token}\s*\)\s*\{.*\}/
+ do_end = /\s+#{token}\s+do(?:\s*;\s*|\s+).*end/
+ regex = /\A\s*cask(?:#{curly.source}|#{do_end.source})\s*\Z/m
+
+ content.match?(regex)
+ end
+
def initialize(content)
@content = content
end
@@ -56,7 +68,8 @@ module Hbc
class FromURILoader < FromPathLoader
def self.can_load?(ref)
- ref.to_s.match?(::URI.regexp)
+ uri_regex = ::URI::DEFAULT_PARSER.make_regexp
+ ref.to_s.match?(Regexp.new('\A' + uri_regex.source + '\Z', uri_regex.options))
end
attr_reader :url
@@ -71,7 +84,7 @@ module Hbc
begin
ohai "Downloading #{url}."
- curl url, "-o", path
+ curl_download url, to: path
rescue ErrorDuringExecution
raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.")
end
@@ -116,6 +129,22 @@ module Hbc
end
end
+ class FromInstanceLoader
+ attr_reader :cask
+
+ def self.can_load?(ref)
+ ref.is_a?(Cask)
+ end
+
+ def initialize(cask)
+ @cask = cask
+ end
+
+ def load
+ cask
+ end
+ end
+
class NullLoader < FromPathLoader
def self.can_load?(*)
true
@@ -131,14 +160,6 @@ module Hbc
end
end
- def self.load_from_file(path)
- FromPathLoader.new(path).load
- end
-
- def self.load_from_string(content)
- FromContentLoader.new(content).load
- end
-
def self.path(ref)
self.for(ref).path
end
@@ -149,6 +170,8 @@ module Hbc
def self.for(ref)
[
+ FromInstanceLoader,
+ FromContentLoader,
FromURILoader,
FromTapLoader,
FromTapPathLoader,
diff --git a/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb b/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb
index 77f85301e..001a9623b 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb
@@ -42,41 +42,32 @@ module Hbc
@args = process_arguments(*args)
end
- def self.warn_unavailable_with_suggestion(cask_token, e)
- exact_match, partial_matches = Search.search(cask_token)
- error_message = e.message
- if exact_match
- error_message.concat(" Did you mean:\n#{exact_match}")
- elsif !partial_matches.empty?
- error_message.concat(" Did you mean one of:\n")
- .concat(Formatter.columns(partial_matches.take(20)))
- end
- onoe error_message
- end
-
private
def casks(alternative: -> { [] })
- return to_enum(:casks, alternative: alternative) unless block_given?
-
- count = 0
-
+ return @casks if defined?(@casks)
casks = args.empty? ? alternative.call : args
+ @casks = casks.map { |cask| CaskLoader.load(cask) }
+ rescue CaskUnavailableError => e
+ reason = [e.reason, suggestion_message(e.token)].join(" ")
+ raise e.class.new(e.token, reason)
+ end
+
+ def suggestion_message(cask_token)
+ exact_match, partial_matches = Search.search(cask_token)
- casks.each do |cask_or_token|
- begin
- yield cask_or_token.respond_to?(:token) ? cask_or_token : CaskLoader.load(cask_or_token)
- count += 1
- rescue CaskUnavailableError => e
- cask_token = cask_or_token
- self.class.warn_unavailable_with_suggestion cask_token, e
- rescue CaskError => e
- onoe e.message
- end
+ if exact_match.nil? && partial_matches.count == 1
+ exact_match = partial_matches.first
end
- return :empty if casks.length.zero?
- (count == casks.length) ? :complete : :incomplete
+ if exact_match
+ "Did you mean “#{exact_match}”?"
+ elsif !partial_matches.empty?
+ "Did you mean one of these?\n"
+ .concat(Formatter.columns(partial_matches.take(20)))
+ else
+ ""
+ end
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/cli/cat.rb b/Library/Homebrew/cask/lib/hbc/cli/cat.rb
index d08c87bea..043080556 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/cat.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/cat.rb
@@ -7,10 +7,6 @@ module Hbc
end
def run
- raise CaskError, "Cat incomplete." if cat_casks == :incomplete
- end
-
- def cat_casks
casks.each do |cask|
puts File.open(cask.sourcefile_path, &:read)
end
diff --git a/Library/Homebrew/cask/lib/hbc/cli/edit.rb b/Library/Homebrew/cask/lib/hbc/cli/edit.rb
index b9485886c..8bce81c52 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/edit.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/edit.rb
@@ -4,21 +4,18 @@ module Hbc
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
- raise ArgumentError, "Only one Cask can be created at a time." if args.count > 1
+ raise ArgumentError, "Only one Cask can be edited at a time." if args.count > 1
end
def run
- cask_token = args.first
- cask_path = begin
- CaskLoader.load(cask_token).sourcefile_path
- rescue CaskUnavailableError => e
- reason = e.reason.empty? ? "" : "#{e.reason} "
- reason.concat("Run #{Formatter.identifier("brew cask create #{e.token}")} to create a new Cask.")
- raise e.class.new(e.token, reason)
- end
-
- odebug "Opening editor for Cask #{cask_token}"
+ cask = casks.first
+ cask_path = cask.sourcefile_path
+ odebug "Opening editor for Cask #{cask.token}"
exec_editor cask_path
+ rescue CaskUnavailableError => e
+ reason = e.reason.empty? ? "" : "#{e.reason} "
+ reason.concat("Run #{Formatter.identifier("brew cask create #{e.token}")} to create a new Cask.")
+ raise e.class.new(e.token, reason)
end
def self.help
diff --git a/Library/Homebrew/cask/lib/hbc/cli/fetch.rb b/Library/Homebrew/cask/lib/hbc/cli/fetch.rb
index e31b1a17c..12c794f5f 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/fetch.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/fetch.rb
@@ -9,10 +9,6 @@ module Hbc
end
def run
- raise CaskError, "Fetch incomplete." if fetch_casks == :incomplete
- end
-
- def fetch_casks
casks.each do |cask|
ohai "Downloading external files for Cask #{cask}"
downloaded_path = Download.new(cask, force: force?).perform
diff --git a/Library/Homebrew/cask/lib/hbc/cli/info.rb b/Library/Homebrew/cask/lib/hbc/cli/info.rb
index d26747e17..f12fe5564 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/info.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/info.rb
@@ -23,6 +23,7 @@ module Hbc
installation_info(cask)
repo_info(cask)
name_info(cask)
+ language_info(cask)
artifact_info(cask)
Installer.print_caveats(cask)
end
@@ -51,6 +52,13 @@ module Hbc
puts cask.name.empty? ? Formatter.error("None") : cask.name
end
+ def self.language_info(cask)
+ return if cask.languages.empty?
+
+ ohai "Languages"
+ puts cask.languages.join(", ")
+ end
+
def self.repo_info(cask)
user, repo, token = QualifiedToken.parse(Hbc.all_tokens.detect { |t| t.split("/").last == cask.token })
@@ -69,12 +77,10 @@ module Hbc
def self.artifact_info(cask)
ohai "Artifacts"
- DSL::ORDINARY_ARTIFACT_TYPES.each do |type|
- next if cask.artifacts[type].empty?
- cask.artifacts[type].each do |artifact|
- activatable_item = (type == :stage_only) ? "<none>" : artifact.first
- puts "#{activatable_item} (#{type})"
- end
+ cask.artifacts.each do |artifact|
+ next unless artifact.respond_to?(:install_phase)
+ next unless DSL::ORDINARY_ARTIFACT_CLASSES.include?(artifact.class)
+ puts artifact.to_s
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/cli/install.rb b/Library/Homebrew/cask/lib/hbc/cli/install.rb
index 0f1a5dd34..9a2116e6a 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/install.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/install.rb
@@ -10,10 +10,6 @@ module Hbc
end
def run
- raise CaskError, "Install incomplete." if install_casks == :incomplete
- end
-
- def install_casks
casks.each do |cask|
begin
Installer.new(cask, binaries: binaries?,
diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb
index cd2679782..a538ffd8c 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb
@@ -12,7 +12,7 @@ module Hbc
if args.all? { |t| t =~ %r{^https?://} && t !~ /\.rb$/ }
self.class.appcask_checkpoint_for_url(args)
else
- self.class.appcask_checkpoint(args, calculate?)
+ self.class.appcask_checkpoint(casks, calculate?)
end
end
@@ -23,33 +23,27 @@ module Hbc
end
end
- def self.appcask_checkpoint(cask_tokens, calculate)
- count = 0
-
- cask_tokens.each do |cask_token|
- cask = CaskLoader.load(cask_token)
-
+ def self.appcask_checkpoint(casks, calculate)
+ casks.each do |cask|
if cask.appcast.nil?
opoo "Cask '#{cask}' is missing an `appcast` stanza."
else
- if calculate
+ checkpoint = if calculate
result = cask.appcast.calculate_checkpoint
-
- checkpoint = result[:checkpoint]
+ result[:checkpoint]
else
- checkpoint = cask.appcast.checkpoint
+ cask.appcast.checkpoint
end
- if checkpoint.nil?
+ if calculate && checkpoint.nil?
onoe "Could not retrieve `appcast` checkpoint for cask '#{cask}': #{result[:command_result].stderr}"
+ elsif casks.count > 1
+ puts "#{checkpoint} #{cask}"
else
- puts((cask_tokens.count > 1) ? "#{checkpoint} #{cask}" : checkpoint)
- count += 1
+ puts checkpoint
end
end
end
-
- count == cask_tokens.count
end
def self.help
diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
index 3673a5391..b83224fb1 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
@@ -59,7 +59,7 @@ module Hbc
end
def modified_cask_files
- @modified_cask_files ||= git_filter_cask_files("AM")
+ @modified_cask_files ||= git_filter_cask_files("AMR")
end
def added_cask_files
diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb
index e21ce86b6..8a38ce1be 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb
@@ -7,10 +7,6 @@ module Hbc
end
def run
- raise CaskError, "Dump incomplete." if dump_casks == :incomplet
- end
-
- def dump_casks
casks.each(&:dumpcask)
end
diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb
index 4515fe931..c04619798 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb
@@ -3,7 +3,7 @@ module Hbc
class InternalStanza < AbstractInternalCommand
# Syntax
#
- # brew cask _stanza <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <cask_token> ... ]
+ # brew cask _stanza <stanza_name> [ --quiet ] [ --table | --yaml ] [ <cask_token> ... ]
#
# If no tokens are given, then data for all Casks is returned.
#
@@ -14,41 +14,16 @@ module Hbc
# Examples
#
# brew cask _stanza appcast --table
- # brew cask _stanza app --table alfred google-chrome adium voicemac logisim vagrant
- # brew cask _stanza url --table alfred google-chrome adium voicemac logisim vagrant
- # brew cask _stanza version --table alfred google-chrome adium voicemac logisim vagrant
- # brew cask _stanza artifacts --table --inspect alfred google-chrome adium voicemac logisim vagrant
- # brew cask _stanza artifacts --table --yaml alfred google-chrome adium voicemac logisim vagrant
+ # brew cask _stanza app --table alfred google-chrome adium vagrant
+ # brew cask _stanza url --table alfred google-chrome adium vagrant
+ # brew cask _stanza version --table alfred google-chrome adium vagrant
+ # brew cask _stanza artifacts --table alfred google-chrome adium vagrant
+ # brew cask _stanza artifacts --table --yaml alfred google-chrome adium vagrant
#
- # TODO: this should be retrievable from Hbc::DSL
- ARTIFACTS = Set.new [
- :app,
- :suite,
- :artifact,
- :prefpane,
- :qlplugin,
- :dictionary,
- :font,
- :service,
- :colorpicker,
- :binary,
- :input_method,
- :internet_plugin,
- :audio_unit_plugin,
- :vst_plugin,
- :vst3_plugin,
- :screen_saver,
- :pkg,
- :installer,
- :stage_only,
- :nested_container,
- :uninstall,
- :preflight,
- :postflight,
- :uninstall_preflight,
- :uninstall_postflight,
- ]
+ ARTIFACTS =
+ DSL::ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key) +
+ DSL::ARTIFACT_BLOCK_CLASSES.map(&:dsl_key)
option "--table", :table, false
option "--quiet", :quiet, false
@@ -68,16 +43,9 @@ module Hbc
@stanza = args.shift.to_sym
@format = :to_yaml if yaml?
- @format = :inspect if inspect?
end
def run
- return unless print_stanzas == :incomplete
- exit 1 if quiet?
- raise CaskError, "Print incomplete."
- end
-
- def print_stanzas
if ARTIFACTS.include?(stanza)
artifact_name = stanza
@stanza = :artifacts
@@ -93,7 +61,7 @@ module Hbc
end
begin
- value = cask.send(@stanza)
+ value = cask.send(stanza)
rescue StandardError
opoo "failure calling '#{stanza}' on Cask '#{cask}'" unless quiet?
puts ""
@@ -106,11 +74,25 @@ module Hbc
next
end
- value = value.fetch(artifact_name).to_a.flatten if artifact_name
+ if stanza == :artifacts
+ value = Hash[
+ value.map do |k, v|
+ v = v.map do |a|
+ next a.to_a if a.respond_to?(:to_a)
+ next a.to_h if a.respond_to?(:to_h)
+ a
+ end
+
+ [k, v]
+ end
+ ]
+
+ value = value.fetch(artifact_name) if artifact_name
+ end
- if @format
- puts value.send(@format)
- elsif artifact_name || value.is_a?(Symbol)
+ if format
+ puts value.send(format)
+ elsif value.is_a?(Symbol)
puts value.inspect
else
puts value.to_s
diff --git a/Library/Homebrew/cask/lib/hbc/cli/list.rb b/Library/Homebrew/cask/lib/hbc/cli/list.rb
index 9d978360e..4a50ae74a 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/list.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/list.rb
@@ -3,6 +3,7 @@ module Hbc
class List < AbstractCommand
option "-1", :one, false
option "--versions", :versions, false
+ option "--full-name", :full_name, false
option "-l", (lambda do |*|
one = true # rubocop:disable Lint/UselessAssignment
@@ -10,8 +11,7 @@ module Hbc
end)
def run
- retval = args.any? ? list : list_installed
- raise CaskError, "Listing incomplete." if retval == :incomplete
+ args.any? ? list : list_installed
end
def list
@@ -23,16 +23,16 @@ module Hbc
elsif versions?
puts self.class.format_versioned(cask)
else
- cask = CaskLoader.load_from_file(cask.installed_caskfile)
+ cask = CaskLoader.load(cask.installed_caskfile)
self.class.list_artifacts(cask)
end
end
end
def self.list_artifacts(cask)
- Artifact.for_cask(cask).each do |artifact|
- summary = artifact.summary
- ohai summary[:english_description], summary[:contents] unless summary.empty?
+ cask.artifacts.group_by(&:class).each do |klass, artifacts|
+ next unless klass.respond_to?(:english_description)
+ ohai klass.english_description, artifacts.map(&:summarize_installed)
end
end
@@ -43,11 +43,11 @@ module Hbc
puts installed_casks.map(&:to_s)
elsif versions?
puts installed_casks.map(&self.class.method(:format_versioned))
+ elsif full_name?
+ puts installed_casks.map(&:full_name).sort &tap_and_name_comparison
elsif !installed_casks.empty?
puts Formatter.columns(installed_casks.map(&:to_s))
end
-
- installed_casks.empty? ? :empty : :complete
end
def self.format_versioned(cask)
diff --git a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb
index 337a2eb9d..408be134d 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb
@@ -1,7 +1,7 @@
module Hbc
class CLI
class Reinstall < Install
- def install_casks
+ def run
casks.each do |cask|
Installer.new(cask, binaries: binaries?,
verbose: verbose?,
diff --git a/Library/Homebrew/cask/lib/hbc/cli/search.rb b/Library/Homebrew/cask/lib/hbc/cli/search.rb
index 643d18d55..d56d0c81f 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/search.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/search.rb
@@ -2,8 +2,12 @@ module Hbc
class CLI
class Search < AbstractCommand
def run
- results = self.class.search(*args)
- self.class.render_results(*results)
+ if args.empty?
+ puts Formatter.columns(CLI.nice_listing(Hbc.all_tokens))
+ else
+ results = self.class.search(*args)
+ self.class.render_results(*results)
+ end
end
def self.extract_regexp(string)
@@ -15,8 +19,18 @@ module Hbc
end
def self.search_remote(query)
- matches = GitHub.search_code("user:caskroom", "path:Casks", "filename:#{query}", "extension:rb")
- [*matches].map do |match|
+ matches = begin
+ GitHub.search_code(
+ user: "caskroom",
+ path: "Casks",
+ filename: query,
+ extension: "rb",
+ )
+ rescue GitHub::Error => error
+ opoo "Error searching on GitHub: #{error}\n"
+ []
+ end
+ matches.map do |match|
tap = Tap.fetch(match["repository"]["full_name"])
next if tap.installed?
"#{tap.name}/#{File.basename(match["path"], ".rb")}"
diff --git a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
index c0697c808..f2059605c 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
@@ -9,10 +9,6 @@ module Hbc
end
def run
- raise CaskError, "Uninstall incomplete." if uninstall_casks == :incomplete
- end
-
- def uninstall_casks
casks.each do |cask|
odebug "Uninstalling Cask #{cask}"
@@ -20,7 +16,7 @@ module Hbc
if cask.installed? && !cask.installed_caskfile.nil?
# use the same cask file that was used for installation, if possible
- cask = CaskLoader.load_from_file(cask.installed_caskfile) if cask.installed_caskfile.exist?
+ cask = CaskLoader.load(cask.installed_caskfile) if cask.installed_caskfile.exist?
end
Installer.new(cask, binaries: binaries?, verbose: verbose?, force: force?).uninstall
diff --git a/Library/Homebrew/cask/lib/hbc/cli/zap.rb b/Library/Homebrew/cask/lib/hbc/cli/zap.rb
index e709f4191..7f5e6785d 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/zap.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/zap.rb
@@ -9,10 +9,6 @@ module Hbc
end
def run
- raise CaskError, "Zap incomplete." if zap_casks == :incomplete
- end
-
- def zap_casks
casks.each do |cask|
odebug "Zapping Cask #{cask}"
Installer.new(cask, verbose: verbose?, force: force?).zap
diff --git a/Library/Homebrew/cask/lib/hbc/container.rb b/Library/Homebrew/cask/lib/hbc/container.rb
index 93e825e03..fab3a3c1c 100644
--- a/Library/Homebrew/cask/lib/hbc/container.rb
+++ b/Library/Homebrew/cask/lib/hbc/container.rb
@@ -4,6 +4,7 @@ require "hbc/container/bzip2"
require "hbc/container/cab"
require "hbc/container/criteria"
require "hbc/container/dmg"
+require "hbc/container/directory"
require "hbc/container/executable"
require "hbc/container/generic_unar"
require "hbc/container/gpg"
@@ -14,6 +15,7 @@ require "hbc/container/otf"
require "hbc/container/pkg"
require "hbc/container/seven_zip"
require "hbc/container/sit"
+require "hbc/container/svn_repository"
require "hbc/container/tar"
require "hbc/container/ttf"
require "hbc/container/rar"
@@ -43,6 +45,7 @@ module Hbc
Xz, # pure xz
Gpg, # GnuPG signed data
Executable,
+ SvnRepository,
]
# for explicit use only (never autodetected):
# Hbc::Container::Naked
diff --git a/Library/Homebrew/cask/lib/hbc/container/base.rb b/Library/Homebrew/cask/lib/hbc/container/base.rb
index 52eb5aab1..78610a1ab 100644
--- a/Library/Homebrew/cask/lib/hbc/container/base.rb
+++ b/Library/Homebrew/cask/lib/hbc/container/base.rb
@@ -20,7 +20,7 @@ module Hbc
unless children.count == 1 &&
!nested_container.directory? &&
- @cask.artifacts[:nested_container].empty? &&
+ @cask.artifacts.none? { |a| a.is_a?(Artifact::NestedContainer) } &&
extract_nested_container(nested_container)
children.each do |src|
diff --git a/Library/Homebrew/cask/lib/hbc/container/criteria.rb b/Library/Homebrew/cask/lib/hbc/container/criteria.rb
index 66ecb8c87..52f171d6a 100644
--- a/Library/Homebrew/cask/lib/hbc/container/criteria.rb
+++ b/Library/Homebrew/cask/lib/hbc/container/criteria.rb
@@ -13,9 +13,11 @@ module Hbc
end
def magic_number(regex)
+ return false if path.directory?
+
# 262: length of the longest regex (currently: Hbc::Container::Tar)
- @magic_number ||= File.open(@path, "rb") { |f| f.read(262) }
- @magic_number =~ regex
+ @magic_number ||= File.open(path, "rb") { |f| f.read(262) }
+ @magic_number.match?(regex)
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/container/directory.rb b/Library/Homebrew/cask/lib/hbc/container/directory.rb
new file mode 100644
index 000000000..e4bb1095b
--- /dev/null
+++ b/Library/Homebrew/cask/lib/hbc/container/directory.rb
@@ -0,0 +1,24 @@
+require "hbc/container/base"
+
+module Hbc
+ class Container
+ class Directory < Base
+ def self.me?(*)
+ false
+ end
+
+ def extract
+ @path.children.each do |child|
+ next if skip_path?(child)
+ FileUtils.cp child, @cask.staged_path
+ end
+ end
+
+ private
+
+ def skip_path?(*)
+ false
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/cask/lib/hbc/container/executable.rb b/Library/Homebrew/cask/lib/hbc/container/executable.rb
index 848f6d4be..af3b36fd1 100644
--- a/Library/Homebrew/cask/lib/hbc/container/executable.rb
+++ b/Library/Homebrew/cask/lib/hbc/container/executable.rb
@@ -8,7 +8,7 @@ module Hbc
return true if criteria.magic_number(/^#!\s*\S+/)
begin
- MachO.open(criteria.path).header.executable?
+ criteria.path.file? && MachO.open(criteria.path).header.executable?
rescue MachO::MagicError
false
end
diff --git a/Library/Homebrew/cask/lib/hbc/container/naked.rb b/Library/Homebrew/cask/lib/hbc/container/naked.rb
index 375d62f7a..dc265c402 100644
--- a/Library/Homebrew/cask/lib/hbc/container/naked.rb
+++ b/Library/Homebrew/cask/lib/hbc/container/naked.rb
@@ -16,7 +16,7 @@ module Hbc
def target_file
return @path.basename if @nested
- URI.decode(File.basename(@cask.url.path))
+ CGI.unescape(File.basename(@cask.url.path))
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/container/svn_repository.rb b/Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
new file mode 100644
index 000000000..cae613b2d
--- /dev/null
+++ b/Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
@@ -0,0 +1,15 @@
+require "hbc/container/directory"
+
+module Hbc
+ class Container
+ class SvnRepository < Directory
+ def self.me?(criteria)
+ criteria.path.join(".svn").directory?
+ end
+
+ def skip_path?(path)
+ path.basename.to_s == ".svn"
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/cask/lib/hbc/download_strategy.rb b/Library/Homebrew/cask/lib/hbc/download_strategy.rb
index 016bb66e6..245ad4ade 100644
--- a/Library/Homebrew/cask/lib/hbc/download_strategy.rb
+++ b/Library/Homebrew/cask/lib/hbc/download_strategy.rb
@@ -10,7 +10,7 @@ module Hbc
class AbstractDownloadStrategy
attr_reader :cask, :name, :url, :uri_object, :version
- def initialize(cask, command = SystemCommand)
+ def initialize(cask, command: SystemCommand)
@cask = cask
@command = command
# TODO: this excess of attributes is a function of integrating
@@ -33,8 +33,8 @@ module Hbc
class HbVCSDownloadStrategy < AbstractDownloadStrategy
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
- def initialize(cask, command = SystemCommand)
- super
+ def initialize(*args, **options)
+ super(*args, **options)
@ref_type, @ref = extract_ref
@clone = Hbc.cache.join(cache_filename)
end
@@ -64,11 +64,6 @@ module Hbc
end
class CurlDownloadStrategy < AbstractDownloadStrategy
- # TODO: should be part of url object
- def mirrors
- @mirrors ||= []
- end
-
def tarball_path
@tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}")
end
@@ -95,13 +90,8 @@ module Hbc
end
end
- def downloaded_size
- temporary_path.size? || 0
- end
-
def _fetch
- odebug "Calling curl with args #{cask_curl_args}"
- curl(*cask_curl_args)
+ curl_download url, *cask_curl_args, to: temporary_path, user_agent: uri_object.user_agent
end
def fetch
@@ -131,33 +121,12 @@ module Hbc
ignore_interrupts { temporary_path.rename(tarball_path) }
end
tarball_path
- rescue CurlDownloadStrategyError
- raise if mirrors.empty?
- puts "Trying a mirror..."
- @url = mirrors.shift
- retry
end
private
def cask_curl_args
- default_curl_args.tap do |args|
- args.concat(user_agent_args)
- args.concat(cookies_args)
- args.concat(referer_args)
- end
- end
-
- def default_curl_args
- [url, "-C", downloaded_size, "-o", temporary_path]
- end
-
- def user_agent_args
- if uri_object.user_agent
- ["-A", uri_object.user_agent]
- else
- []
- end
+ cookies_args + referer_args
end
def cookies_args
@@ -191,8 +160,7 @@ module Hbc
class CurlPostDownloadStrategy < CurlDownloadStrategy
def cask_curl_args
- super
- default_curl_args.concat(post_args)
+ super.concat(post_args)
end
def post_args
@@ -225,8 +193,8 @@ module Hbc
# super does not provide checks for already-existing downloads
def fetch
- if tarball_path.exist?
- puts "Already downloaded: #{tarball_path}"
+ if cached_location.directory?
+ puts "Already downloaded: #{cached_location}"
else
@url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://}
ohai "Checking out #{@url}"
@@ -252,9 +220,8 @@ module Hbc
else
fetch_repo @clone, @url
end
- compress
end
- tarball_path
+ cached_location
end
# This primary reason for redefining this method is the trust_cert
@@ -288,10 +255,6 @@ module Hbc
print_stderr: false)
end
- def tarball_path
- @tarball_path ||= cached_location.dirname.join(cached_location.basename.to_s + "-#{@cask.version}.tar")
- end
-
def shell_quote(str)
# Oh god escaping shell args.
# See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/
@@ -304,35 +267,5 @@ module Hbc
yield name, url
end
end
-
- private
-
- # TODO/UPDATE: the tar approach explained below is fragile
- # against challenges such as case-sensitive filesystems,
- # and must be re-implemented.
- #
- # Seems nutty: we "download" the contents into a tape archive.
- # Why?
- # * A single file is tractable to the rest of the Cask toolchain,
- # * An alternative would be to create a Directory container type.
- # However, some type of file-serialization trick would still be
- # needed in order to enable calculating a single checksum over
- # a directory. So, in that alternative implementation, the
- # special cases would propagate outside this class, including
- # the use of tar or equivalent.
- # * SubversionDownloadStrategy.cached_location is not versioned
- # * tarball_path provides a needed return value for our overridden
- # fetch method.
- # * We can also take this private opportunity to strip files from
- # the download which are protocol-specific.
-
- def compress
- Dir.chdir(cached_location) do
- @command.run!("/usr/bin/tar",
- args: ['-s/^\.//', "--exclude", ".svn", "-cf", Pathname.new(tarball_path), "--", "."],
- print_stderr: false)
- end
- clear_cache
- end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl.rb b/Library/Homebrew/cask/lib/hbc/dsl.rb
index 8ad206c2f..2db2c66a9 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl.rb
@@ -1,6 +1,8 @@
require "set"
require "locale"
+require "hbc/artifact"
+
require "hbc/dsl/appcast"
require "hbc/dsl/base"
require "hbc/dsl/caveats"
@@ -8,7 +10,6 @@ require "hbc/dsl/conflicts_with"
require "hbc/dsl/container"
require "hbc/dsl/depends_on"
require "hbc/dsl/gpg"
-require "hbc/dsl/installer"
require "hbc/dsl/postflight"
require "hbc/dsl/preflight"
require "hbc/dsl/stanza_proxy"
@@ -18,39 +19,35 @@ require "hbc/dsl/version"
module Hbc
class DSL
- ORDINARY_ARTIFACT_TYPES = [
- :app,
- :artifact,
- :audio_unit_plugin,
- :binary,
- :colorpicker,
- :dictionary,
- :font,
- :input_method,
- :internet_plugin,
- :pkg,
- :prefpane,
- :qlplugin,
- :screen_saver,
- :service,
- :stage_only,
- :suite,
- :vst_plugin,
- :vst3_plugin,
+ ORDINARY_ARTIFACT_CLASSES = [
+ Artifact::Installer,
+ Artifact::App,
+ Artifact::Artifact,
+ Artifact::AudioUnitPlugin,
+ Artifact::Binary,
+ Artifact::Colorpicker,
+ Artifact::Dictionary,
+ Artifact::Font,
+ Artifact::InputMethod,
+ Artifact::InternetPlugin,
+ Artifact::Pkg,
+ Artifact::Prefpane,
+ Artifact::Qlplugin,
+ Artifact::ScreenSaver,
+ Artifact::Service,
+ Artifact::StageOnly,
+ Artifact::Suite,
+ Artifact::VstPlugin,
+ Artifact::Vst3Plugin,
+ Artifact::Uninstall,
+ Artifact::Zap,
].freeze
- ACTIVATABLE_ARTIFACT_TYPES = ([:installer, *ORDINARY_ARTIFACT_TYPES] - [:stage_only]).freeze
-
- SPECIAL_ARTIFACT_TYPES = [
- :uninstall,
- :zap,
- ].freeze
+ ACTIVATABLE_ARTIFACT_CLASSES = ORDINARY_ARTIFACT_CLASSES - [Artifact::StageOnly]
- ARTIFACT_BLOCK_TYPES = [
- :preflight,
- :postflight,
- :uninstall_preflight,
- :uninstall_postflight,
+ ARTIFACT_BLOCK_CLASSES = [
+ Artifact::PreflightBlock,
+ Artifact::PostflightBlock,
].freeze
DSL_METHODS = Set.new [
@@ -66,21 +63,23 @@ module Hbc
:gpg,
:homepage,
:language,
+ :languages,
:name,
:sha256,
:staged_path,
:url,
:version,
:appdir,
- *ORDINARY_ARTIFACT_TYPES,
- *ACTIVATABLE_ARTIFACT_TYPES,
- *SPECIAL_ARTIFACT_TYPES,
- *ARTIFACT_BLOCK_TYPES,
+ *ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key),
+ *ACTIVATABLE_ARTIFACT_CLASSES.map(&:dsl_key),
+ *ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] },
].freeze
- attr_reader :token
- def initialize(token)
- @token = token
+ attr_reader :cask, :token
+
+ def initialize(cask)
+ @cask = cask
+ @token = cask.token
end
def name(*args)
@@ -93,12 +92,14 @@ module Hbc
return instance_variable_get("@#{stanza}") if should_return
if instance_variable_defined?("@#{stanza}")
- raise CaskInvalidError.new(token, "'#{stanza}' stanza may only appear once")
+ raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
end
instance_variable_set("@#{stanza}", yield)
+ rescue CaskInvalidError
+ raise
rescue StandardError => e
- raise CaskInvalidError.new(token, "'#{stanza}' stanza failed with: #{e}")
+ raise CaskInvalidError.new(cask, "'#{stanza}' stanza failed with: #{e}")
end
def homepage(homepage = nil)
@@ -106,19 +107,21 @@ module Hbc
end
def language(*args, default: false, &block)
- if !args.empty? && block_given?
+ if args.empty?
+ language_eval
+ elsif block_given?
@language_blocks ||= {}
@language_blocks[args] = block
return unless default
unless @language_blocks.default.nil?
- raise CaskInvalidError.new(token, "Only one default language may be defined")
+ raise CaskInvalidError.new(cask, "Only one default language may be defined.")
end
@language_blocks.default = block
else
- language_eval
+ raise CaskInvalidError.new(cask, "No block given to language stanza.")
end
end
@@ -127,6 +130,10 @@ module Hbc
return @language = nil if @language_blocks.nil? || @language_blocks.empty?
+ if @language_blocks.default.nil?
+ raise CaskInvalidError.new(cask, "No default language specified.")
+ end
+
MacOS.languages.map(&Locale.method(:parse)).each do |locale|
key = @language_blocks.keys.detect do |strings|
strings.any? { |string| locale.include?(string) }
@@ -140,6 +147,12 @@ module Hbc
@language = @language_blocks.default.call
end
+ def languages
+ return [] if @language_blocks.nil?
+
+ @language_blocks.keys.flatten
+ end
+
def url(*args, &block)
set_unique_stanza(:url, args.empty? && !block_given?) do
begin
@@ -162,8 +175,8 @@ module Hbc
begin
DSL::Container.new(*args).tap do |container|
# TODO: remove this backward-compatibility section after removing nested_container
- if container && container.nested
- artifacts[:nested_container] << container.nested
+ if container&.nested
+ artifacts.add(Artifact::NestedContainer.new(cask, container.nested))
end
end
end
@@ -173,7 +186,7 @@ module Hbc
def version(arg = nil)
set_unique_stanza(:version, arg.nil?) do
if !arg.is_a?(String) && arg != :latest
- raise CaskInvalidError.new(token, "invalid 'version' value: '#{arg.inspect}'")
+ raise CaskInvalidError.new(cask, "invalid 'version' value: '#{arg.inspect}'")
end
DSL::Version.new(arg)
end
@@ -182,7 +195,7 @@ module Hbc
def sha256(arg = nil)
set_unique_stanza(:sha256, arg.nil?) do
if !arg.is_a?(String) && arg != :no_check
- raise CaskInvalidError.new(token, "invalid 'sha256' value: '#{arg.inspect}'")
+ raise CaskInvalidError.new(cask, "invalid 'sha256' value: '#{arg.inspect}'")
end
arg
end
@@ -195,7 +208,7 @@ module Hbc
begin
@depends_on.load(*args)
rescue RuntimeError => e
- raise CaskInvalidError.new(token, e)
+ raise CaskInvalidError.new(cask, e)
end
@depends_on
end
@@ -206,7 +219,7 @@ module Hbc
end
def artifacts
- @artifacts ||= Hash.new { |hash, key| hash[key] = Set.new }
+ @artifacts ||= SortedSet.new
end
def caskroom_path
@@ -237,39 +250,27 @@ module Hbc
set_unique_stanza(:auto_updates, auto_updates.nil?) { auto_updates }
end
- ORDINARY_ARTIFACT_TYPES.each do |type|
- define_method(type) do |*args|
- if type == :stage_only
- if args != [true]
- raise CaskInvalidError.new(token, "'stage_only' takes a single argument: true")
+ ORDINARY_ARTIFACT_CLASSES.each do |klass|
+ define_method(klass.dsl_key) do |*args|
+ begin
+ if [*artifacts.map(&:class), klass].include?(Artifact::StageOnly) && (artifacts.map(&:class) & ACTIVATABLE_ARTIFACT_CLASSES).any?
+ raise CaskInvalidError.new(cask, "'stage_only' must be the only activatable artifact.")
end
- unless (artifacts.keys & ACTIVATABLE_ARTIFACT_TYPES).empty?
- raise CaskInvalidError.new(token, "'stage_only' must be the only activatable artifact")
- end
+ artifacts.add(klass.from_args(cask, *args))
+ rescue CaskInvalidError
+ raise
+ rescue StandardError => e
+ raise CaskInvalidError.new(cask, "invalid '#{klass.dsl_key}' stanza: #{e}")
end
-
- artifacts[type].add(args)
- end
- end
-
- def installer(*args)
- return artifacts[:installer] if args.empty?
- artifacts[:installer] << DSL::Installer.new(*args)
- raise "'stage_only' must be the only activatable artifact" if artifacts.key?(:stage_only)
- rescue StandardError => e
- raise CaskInvalidError.new(token, e)
- end
-
- SPECIAL_ARTIFACT_TYPES.each do |type|
- define_method(type) do |*args|
- artifacts[type].merge(args)
end
end
- ARTIFACT_BLOCK_TYPES.each do |type|
- define_method(type) do |&block|
- artifacts[type] << block
+ ARTIFACT_BLOCK_CLASSES.each do |klass|
+ [klass.dsl_key, klass.uninstall_dsl_key].each do |dsl_key|
+ define_method(dsl_key) do |&block|
+ artifacts.add(klass.new(cask, dsl_key => block))
+ end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb b/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb
index d302d0946..f3994b81f 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb
@@ -3,16 +3,20 @@ require "hbc/system_command"
module Hbc
class DSL
class Appcast
- attr_reader :parameters, :checkpoint
+ attr_reader :uri, :checkpoint, :parameters
- def initialize(uri, parameters = {})
- @parameters = parameters
- @uri = UnderscoreSupportingURI.parse(uri)
- @checkpoint = @parameters[:checkpoint]
+ def initialize(uri, **parameters)
+ @uri = URI(uri)
+ @parameters = parameters
+ @checkpoint = parameters[:checkpoint]
end
def calculate_checkpoint
- result = SystemCommand.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--fail", @uri], print_stderr: false)
+ curl_executable, *args = curl_args(
+ "--compressed", "--location", "--fail", uri,
+ user_agent: :fake
+ )
+ result = SystemCommand.run(curl_executable, args: args, print_stderr: false)
checkpoint = if result.success?
processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "")
@@ -26,11 +30,11 @@ module Hbc
end
def to_yaml
- [@uri, @parameters].to_yaml
+ [uri, parameters].to_yaml
end
def to_s
- @uri.to_s
+ uri.to_s
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/base.rb b/Library/Homebrew/cask/lib/hbc/dsl/base.rb
index 63df847e9..b97c4e104 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/base.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/base.rb
@@ -10,14 +10,14 @@ module Hbc
def_delegators :@cask, :token, :version, :caskroom_path, :staged_path, :appdir, :language
- def system_command(executable, options = {})
- @command.run!(executable, options)
+ def system_command(executable, **options)
+ @command.run!(executable, **options)
end
def method_missing(method, *)
if method
underscored_class = self.class.name.gsub(/([[:lower:]])([[:upper:]][[:lower:]])/, '\1_\2').downcase
- section = underscored_class.downcase.split("::").last
+ section = underscored_class.split("::").last
Utils.method_missing_message(method, @cask.to_s, section)
nil
else
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb b/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
index 402574456..7d373b5f3 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
@@ -48,7 +48,7 @@ module Hbc
brew cask install java
EOS
- elsif java_version.include?("8") || java_version.include?("+")
+ elsif java_version.include?("9") || java_version.include?("+")
puts <<-EOS.undent
#{@cask} requires Java #{java_version}. You can install the latest version with
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/conflicts_with.rb b/Library/Homebrew/cask/lib/hbc/dsl/conflicts_with.rb
index 948348239..dfaa55a5c 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/conflicts_with.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/conflicts_with.rb
@@ -10,25 +10,20 @@ module Hbc
:java,
]
- attr_accessor(*VALID_KEYS)
- attr_accessor :pairs
+ attr_reader *VALID_KEYS
def initialize(pairs = {})
@pairs = pairs
+
+ VALID_KEYS.each do |key|
+ instance_variable_set("@#{key}", Set.new)
+ end
+
pairs.each do |key, value|
raise "invalid conflicts_with key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
- writer_method = "#{key}=".to_sym
- send(writer_method, value)
+ instance_variable_set("@#{key}", instance_variable_get("@#{key}").merge([*value]))
end
end
-
- def to_yaml
- @pairs.to_yaml
- end
-
- def to_s
- @pairs.inspect
- end
end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/gpg.rb b/Library/Homebrew/cask/lib/hbc/dsl/gpg.rb
index b49ebb97c..99b39d43f 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/gpg.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/gpg.rb
@@ -14,11 +14,11 @@ module Hbc
def initialize(signature, parameters = {})
@parameters = parameters
- @signature = UnderscoreSupportingURI.parse(signature)
+ @signature = URI(signature)
parameters.each do |hkey, hvalue|
raise "invalid 'gpg' parameter: '#{hkey.inspect}'" unless VALID_PARAMETERS.include?(hkey)
writer_method = "#{hkey}=".to_sym
- hvalue = UnderscoreSupportingURI.parse(hvalue) if hkey == :key_url
+ hvalue = URI(hvalue) if hkey == :key_url
valid_id?(hvalue) if hkey == :key_id
send(writer_method, hvalue)
end
@@ -35,7 +35,7 @@ module Hbc
end
def to_yaml
- # bug, :key_url value is not represented as an instance of Hbc::UnderscoreSupportingURI
+ # bug, :key_url value is not represented as an instance of URI
[@signature, @parameters].to_yaml
end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/installer.rb b/Library/Homebrew/cask/lib/hbc/dsl/installer.rb
deleted file mode 100644
index b01b28d76..000000000
--- a/Library/Homebrew/cask/lib/hbc/dsl/installer.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-module Hbc
- class DSL
- class Installer
- VALID_KEYS = Set.new [
- :manual,
- :script,
- ]
-
- attr_accessor(*VALID_KEYS)
-
- def initialize(*parameters)
- raise CaskInvalidError.new(token, "'installer' stanza requires an argument") if parameters.empty?
- parameters = {}.merge(*parameters)
- if parameters.key?(:script) && !parameters[:script].respond_to?(:key?)
- if parameters.key?(:executable)
- raise CaskInvalidError.new(token, "'installer' stanza gave arguments for both :script and :executable")
- end
- parameters[:executable] = parameters[:script]
- parameters.delete(:script)
- parameters = { script: parameters }
- end
- unless parameters.keys.length == 1
- raise "invalid 'installer' stanza: only one of #{VALID_KEYS.inspect} is permitted"
- end
- key = parameters.keys.first
- raise "invalid 'installer' stanza key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
- writer_method = "#{key}=".to_sym
- send(writer_method, parameters[key])
- end
- end
- end
-end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/version.rb b/Library/Homebrew/cask/lib/hbc/dsl/version.rb
index d73205f52..9605feb57 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/version.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/version.rb
@@ -49,7 +49,7 @@ module Hbc
end
end
- DIVIDERS.keys.each do |divider|
+ DIVIDERS.each_key do |divider|
define_divider_methods(divider)
end
diff --git a/Library/Homebrew/cask/lib/hbc/exceptions.rb b/Library/Homebrew/cask/lib/hbc/exceptions.rb
index 1a246be65..f7f9e43b6 100644
--- a/Library/Homebrew/cask/lib/hbc/exceptions.rb
+++ b/Library/Homebrew/cask/lib/hbc/exceptions.rb
@@ -17,6 +17,19 @@ module Hbc
end
end
+ class CaskConflictError < AbstractCaskErrorWithToken
+ attr_reader :conflicting_cask
+
+ def initialize(token, conflicting_cask)
+ super(token)
+ @conflicting_cask = conflicting_cask
+ end
+
+ def to_s
+ "Cask '#{token}' conflicts with '#{conflicting_cask}'."
+ end
+ end
+
class CaskUnavailableError < AbstractCaskErrorWithToken
def to_s
"Cask '#{token}' is unavailable" << (reason.empty? ? "." : ": #{reason}")
diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb
index 53210ed4b..68b9595e1 100644
--- a/Library/Homebrew/cask/lib/hbc/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/installer.rb
@@ -86,6 +86,8 @@ module Hbc
raise CaskAlreadyInstalledError, @cask
end
+ check_conflicts
+
print_caveats
fetch
uninstall_existing_cask if @reinstall
@@ -98,6 +100,21 @@ module Hbc
puts summary
end
+ def check_conflicts
+ return unless @cask.conflicts_with
+
+ @cask.conflicts_with.cask.each do |conflicting_cask|
+ begin
+ conflicting_cask = CaskLoader.load(conflicting_cask)
+ if conflicting_cask.installed?
+ raise CaskConflictError.new(@cask, conflicting_cask)
+ end
+ rescue CaskUnavailableError
+ next # Ignore conflicting Casks that do not exist.
+ end
+ end
+ end
+
def reinstall
odebug "Hbc::Installer#reinstall"
@reinstall = true
@@ -109,7 +126,7 @@ module Hbc
# use the same cask file that was used for installation, if possible
installed_caskfile = @cask.installed_caskfile
- installed_cask = installed_caskfile.exist? ? CaskLoader.load_from_file(installed_caskfile) : @cask
+ installed_cask = installed_caskfile.exist? ? CaskLoader.load(installed_caskfile) : @cask
# Always force uninstallation, ignore method parameter
Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true).uninstall
@@ -142,7 +159,7 @@ module Hbc
odebug "Extracting primary container"
FileUtils.mkdir_p @cask.staged_path
- container = if @cask.container && @cask.container.type
+ container = if @cask.container&.type
Container.from_type(@cask.container.type)
else
Container.for_path(@downloaded_path, @command)
@@ -160,7 +177,7 @@ module Hbc
already_installed_artifacts = []
odebug "Installing artifacts"
- artifacts = Artifact.for_cask(@cask, command: @command, verbose: verbose?, force: force?)
+ artifacts = @cask.artifacts
odebug "#{artifacts.length} artifact/s defined", artifacts
artifacts.each do |artifact|
@@ -171,7 +188,7 @@ module Hbc
next unless binaries?
end
- artifact.install_phase
+ artifact.install_phase(command: @command, verbose: verbose?, force: force?)
already_installed_artifacts.unshift(artifact)
end
rescue StandardError => e
@@ -179,7 +196,7 @@ module Hbc
already_installed_artifacts.each do |artifact|
next unless artifact.respond_to?(:uninstall_phase)
odebug "Reverting installation of artifact of class #{artifact.class}"
- artifact.uninstall_phase
+ artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
end
ensure
purge_versioned_files
@@ -344,7 +361,7 @@ module Hbc
savedir = @cask.metadata_subdir("Casks", timestamp: :now, create: true)
FileUtils.copy @cask.sourcefile_path, savedir
- old_savedir.rmtree unless old_savedir.nil?
+ old_savedir&.rmtree
end
def uninstall
@@ -357,25 +374,27 @@ module Hbc
def uninstall_artifacts
odebug "Un-installing artifacts"
- artifacts = Artifact.for_cask(@cask, command: @command, verbose: verbose?, force: force?)
+ artifacts = @cask.artifacts
odebug "#{artifacts.length} artifact/s defined", artifacts
artifacts.each do |artifact|
next unless artifact.respond_to?(:uninstall_phase)
odebug "Un-installing artifact of class #{artifact.class}"
- artifact.uninstall_phase
+ artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
end
end
def zap
ohai %Q(Implied "brew cask uninstall #{@cask}")
uninstall_artifacts
- if Artifact::Zap.me?(@cask)
- ohai "Dispatching zap stanza"
- Artifact::Zap.new(@cask, command: @command).zap_phase
- else
+ if (zap_stanzas = @cask.artifacts.select { |a| a.is_a?(Artifact::Zap) }).empty?
opoo "No zap stanza present for Cask '#{@cask}'"
+ else
+ ohai "Dispatching zap stanza"
+ zap_stanzas.each do |stanza|
+ stanza.zap_phase(command: @command, verbose: verbose?, force: force?)
+ end
end
ohai "Removing all staged versions of Cask '#{@cask}'"
purge_caskroom_path
diff --git a/Library/Homebrew/cask/lib/hbc/staged.rb b/Library/Homebrew/cask/lib/hbc/staged.rb
index c1aa01b29..da097e0cf 100644
--- a/Library/Homebrew/cask/lib/hbc/staged.rb
+++ b/Library/Homebrew/cask/lib/hbc/staged.rb
@@ -4,7 +4,7 @@ module Hbc
index = 0 if index == :first
index = 1 if index == :second
index = -1 if index == :last
- Hbc.appdir.join(@cask.artifacts[:app].to_a.at(index).first, "Contents", "Info.plist")
+ @cask.artifacts.select { |a| a.is_a?(Artifact::App) }.at(index).target.join("Contents", "Info.plist")
end
def plist_exec(cmd)
diff --git a/Library/Homebrew/cask/lib/hbc/system_command.rb b/Library/Homebrew/cask/lib/hbc/system_command.rb
index 901617b71..be083c29e 100644
--- a/Library/Homebrew/cask/lib/hbc/system_command.rb
+++ b/Library/Homebrew/cask/lib/hbc/system_command.rb
@@ -61,7 +61,7 @@ module Hbc
end
def assert_success
- return if processed_status && processed_status.success?
+ return if processed_status&.success?
raise CaskCommandFailedError.new(command, processed_output[:stdout], processed_output[:stderr], processed_status)
end
@@ -112,11 +112,7 @@ module Hbc
processed_output[:stderr],
processed_status.exitstatus)
end
- end
-end
-module Hbc
- class SystemCommand
class Result
attr_accessor :command, :stdout, :stderr, :exit_status
diff --git a/Library/Homebrew/cask/lib/hbc/underscore_supporting_uri.rb b/Library/Homebrew/cask/lib/hbc/underscore_supporting_uri.rb
deleted file mode 100644
index 8f8f66f43..000000000
--- a/Library/Homebrew/cask/lib/hbc/underscore_supporting_uri.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require "uri"
-
-module Hbc
- module UnderscoreSupportingURI
- def self.parse(maybe_uri)
- return nil if maybe_uri.nil?
- URI.parse(maybe_uri)
- rescue URI::InvalidURIError => e
- scheme, host, path = simple_parse(maybe_uri)
- raise e unless path && host.include?("_")
- URI.parse(without_host_underscores(scheme, host, path)).tap do |uri|
- uri.instance_variable_set("@host", host)
- end
- end
-
- def self.simple_parse(maybe_uri)
- scheme, host_and_path = maybe_uri.split("://")
- host, path = host_and_path.split("/", 2)
- [scheme, host, path]
- rescue StandardError
- nil
- end
-
- def self.without_host_underscores(scheme, host, path)
- ["#{scheme}:/", host.tr("_", "-"), path].join("/")
- end
- end
-end
diff --git a/Library/Homebrew/cask/lib/hbc/url.rb b/Library/Homebrew/cask/lib/hbc/url.rb
index 15da2ced2..35020c5db 100644
--- a/Library/Homebrew/cask/lib/hbc/url.rb
+++ b/Library/Homebrew/cask/lib/hbc/url.rb
@@ -1,8 +1,6 @@
module Hbc
class URL
- FAKE_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io".freeze
-
- attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data
+ attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data, :user_agent
extend Forwardable
def_delegators :uri, :path, :scheme, :to_s
@@ -16,8 +14,8 @@ module Hbc
end
def initialize(uri, options = {})
- @uri = Hbc::UnderscoreSupportingURI.parse(uri)
- @user_agent = options[:user_agent]
+ @uri = URI(uri)
+ @user_agent = options.fetch(:user_agent, :default)
@cookies = options[:cookies]
@referer = options[:referer]
@using = options[:using]
@@ -25,10 +23,5 @@ module Hbc
@trust_cert = options[:trust_cert]
@data = options[:data]
end
-
- def user_agent
- return FAKE_USER_AGENT if @user_agent == :fake
- @user_agent
- end
end
end
diff --git a/Library/Homebrew/cask/lib/hbc/verify/gpg.rb b/Library/Homebrew/cask/lib/hbc/verify/gpg.rb
index dbb537756..f4996a5b5 100644
--- a/Library/Homebrew/cask/lib/hbc/verify/gpg.rb
+++ b/Library/Homebrew/cask/lib/hbc/verify/gpg.rb
@@ -33,7 +33,7 @@ module Hbc
meta_dir = cached || cask.metadata_subdir("gpg", :now, true)
sig_path = meta_dir.join("signature.asc")
- curl(cask.gpg.signature, "-o", sig_path.to_s) unless cached || force
+ curl_download cask.gpg.signature, to: sig_path unless cached || force
sig_path
end
diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb
index 578b292fa..1849ea79b 100644
--- a/Library/Homebrew/caveats.rb
+++ b/Library/Homebrew/caveats.rb
@@ -163,7 +163,7 @@ class Caveats
def plist_caveats
s = []
- if f.plist || (keg && keg.plist_installed?)
+ if f.plist || (keg&.plist_installed?)
plist_domain = f.plist_path.basename(".plist")
# we readlink because this path probably doesn't exist since caveats
diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb
index d1f0b2516..340161204 100644
--- a/Library/Homebrew/cleanup.rb
+++ b/Library/Homebrew/cleanup.rb
@@ -6,6 +6,10 @@ module Homebrew
module Cleanup
@disk_cleanup_size = 0
+ class << self
+ attr_reader :disk_cleanup_size
+ end
+
module_function
def cleanup
@@ -21,10 +25,6 @@ module Homebrew
@disk_cleanup_size += path_size
end
- def disk_cleanup_size
- @disk_cleanup_size
- end
-
def unremovable_kegs
@unremovable_kegs ||= []
end
diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb
index bbf0c1b0b..de7aa4a51 100644
--- a/Library/Homebrew/cmd/deps.rb
+++ b/Library/Homebrew/cmd/deps.rb
@@ -1,4 +1,4 @@
-#: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] <formulae>:
+#: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--include-requirements`] <formulae>:
#: Show dependencies for <formulae>. When given multiple formula arguments,
#: show the intersection of dependencies for <formulae>.
#:
@@ -19,15 +19,22 @@
#: <formulae>. To include the `:build` type dependencies, pass `--include-build`.
#: Similarly, pass `--include-optional` to include `:optional` dependencies.
#: To skip `:recommended` type dependencies, pass `--skip-recommended`.
+#: To include requirements in addition to dependencies, pass `--include-requirements`.
#:
-#: * `deps` `--tree` [<filters>] (<formulae>|`--installed`):
+#: * `deps` `--tree` [`--1`] [<filters>] [`--annotate`] (<formulae>|`--installed`):
#: Show dependencies as a tree. When given multiple formula arguments, output
#: individual trees for every formula.
#:
+#: If `--1` is passed, only one level of children is displayed.
+#:
#: If `--installed` is passed, output a tree for every installed formula.
#:
#: The <filters> placeholder is any combination of options `--include-build`,
-#: `--include-optional`, and `--skip-recommended` as documented above.
+#: `--include-optional`, `--skip-recommended`, and `--include-requirements` as
+#: documented above.
+#:
+#: If `--annotate` is passed, the build, optional, and recommended dependencies
+#: are marked as such in the output.
#:
#: * `deps` [<filters>] (`--installed`|`--all`):
#: Show dependencies for installed or all available formulae. Every line of
@@ -37,6 +44,10 @@
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--include-optional`, and `--skip-recommended` as documented above.
+# The undocumented `--for-each` option will switch into the mode used by `deps --all`,
+# but only list dependencies for specified formula, one specified formula per line.
+# This is used for debugging the `--installed`/`--all` display mode.
+
# encoding: UTF-8
require "formula"
@@ -52,20 +63,26 @@ module Homebrew
all?: ARGV.include?("--all"),
topo_order?: ARGV.include?("-n"),
union?: ARGV.include?("--union"),
+ for_each?: ARGV.include?("--for-each"),
)
- if mode.installed? && mode.tree?
- puts_deps_tree Formula.installed
+ if mode.tree?
+ if mode.installed?
+ puts_deps_tree Formula.installed, !ARGV.one?
+ else
+ raise FormulaUnspecifiedError if ARGV.named.empty?
+ puts_deps_tree ARGV.formulae, !ARGV.one?
+ end
elsif mode.all?
puts_deps Formula
- elsif mode.tree?
- raise FormulaUnspecifiedError if ARGV.named.empty?
- puts_deps_tree ARGV.formulae
elsif ARGV.named.empty?
raise FormulaUnspecifiedError unless mode.installed?
puts_deps Formula.installed
+ elsif mode.for_each?
+ puts_deps ARGV.formulae
else
all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&))
+ all_deps = condense_requirements(all_deps)
all_deps = all_deps.select(&:installed?) if mode.installed?
all_deps = all_deps.map(&method(:dep_display_name)).uniq
all_deps.sort! unless mode.topo_order?
@@ -73,24 +90,59 @@ module Homebrew
end
end
- def dep_display_name(d)
- ARGV.include?("--full-name") ? d.to_formula.full_name : d.name
+ def condense_requirements(deps)
+ if ARGV.include?("--include-requirements")
+ deps
+ else
+ deps.map do |dep|
+ if dep.is_a? Dependency
+ dep
+ elsif dep.default_formula?
+ dep.to_dependency
+ end
+ end.compact
+ end
+ end
+
+ def dep_display_name(dep)
+ str = if dep.is_a? Requirement
+ if ARGV.include?("--include-requirements")
+ if dep.default_formula?
+ ":#{dep.display_s} (#{dep_display_name(dep.to_dependency)})"
+ else
+ ":#{dep.display_s}"
+ end
+ elsif dep.default_formula?
+ dep_display_name(dep.to_dependency)
+ else
+ # This shouldn't happen, but we'll put something here to help debugging
+ "::#{dep.name}"
+ end
+ else
+ ARGV.include?("--full-name") ? dep.to_formula.full_name : dep.name
+ end
+ if ARGV.include?("--annotate")
+ str = "#{str} [build]" if dep.build?
+ str = "#{str} [optional" if dep.optional?
+ str = "#{str} [recommended]" if dep.recommended?
+ end
+ str
end
def deps_for_formula(f, recursive = false)
includes = []
ignores = []
- if ARGV.include? "--include-build"
+ if ARGV.include?("--include-build")
includes << "build?"
else
ignores << "build?"
end
- if ARGV.include? "--include-optional"
+ if ARGV.include?("--include-optional")
includes << "optional?"
else
ignores << "optional?"
end
- ignores << "recommended?" if ARGV.include? "--skip-recommended"
+ ignores << "recommended?" if ARGV.include?("--skip-recommended")
if recursive
deps = f.recursive_dependencies do |dependent, dep|
@@ -120,7 +172,7 @@ module Homebrew
end
end
- deps + reqs.select(&:default_formula?).map(&:to_dependency)
+ deps + reqs.to_a
end
def deps_for_formulae(formulae, recursive = false, &block)
@@ -129,41 +181,55 @@ module Homebrew
def puts_deps(formulae)
formulae.each do |f|
- deps = deps_for_formula(f).sort_by(&:name).map(&method(:dep_display_name))
+ deps = deps_for_formula(f)
+ deps = condense_requirements(deps)
+ deps = deps.sort_by(&:name).map(&method(:dep_display_name))
puts "#{f.full_name}: #{deps.join(" ")}"
end
end
- def puts_deps_tree(formulae)
+ def puts_deps_tree(formulae, recursive = false)
formulae.each do |f|
- puts "#{f.full_name} (required dependencies)"
- recursive_deps_tree(f, "")
+ puts f.full_name
+ @dep_stack = []
+ recursive_deps_tree(f, "", recursive)
puts
end
end
- def recursive_deps_tree(f, prefix)
- reqs = f.requirements.select(&:default_formula?)
- deps = f.deps.default
- max = reqs.length - 1
- reqs.each_with_index do |req, i|
- chr = if i == max && deps.empty?
+ def recursive_deps_tree(f, prefix, recursive)
+ reqs = f.requirements
+ deps = f.deps
+ dependables = reqs + deps
+ dependables = dependables.reject(&:optional?) unless ARGV.include?("--include-optional")
+ dependables = dependables.reject(&:build?) unless ARGV.include?("--include-build")
+ dependables = dependables.reject(&:recommended?) if ARGV.include?("--skip-recommended")
+ max = dependables.length - 1
+ @dep_stack.push f.name
+ dependables.each_with_index do |dep, i|
+ next if !ARGV.include?("--include-requirements") && dep.is_a?(Requirement) && !dep.default_formula?
+ tree_lines = if i == max
"└──"
else
"├──"
end
- puts prefix + "#{chr} :#{dep_display_name(req.to_dependency)}"
- end
- max = deps.length - 1
- deps.each_with_index do |dep, i|
- chr = if i == max
- "└──"
+ display_s = "#{tree_lines} #{dep_display_name(dep)}"
+ is_circular = @dep_stack.include?(dep.name)
+ display_s = "#{display_s} (CIRCULAR DEPENDENCY)" if is_circular
+ puts "#{prefix}#{display_s}"
+ next if !recursive || is_circular
+ prefix_addition = if i == max
+ " "
else
- "├──"
+ "│ "
+ end
+ if dep.is_a?(Requirement) && dep.default_formula?
+ recursive_deps_tree(Formulary.factory(dep.to_dependency.name), prefix + prefix_addition, true)
+ end
+ if dep.is_a? Dependency
+ recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_addition, true)
end
- prefix_ext = (i == max) ? " " : "│ "
- puts prefix + "#{chr} #{dep_display_name(dep)}"
- recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_ext)
end
+ @dep_stack.pop
end
end
diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb
index 006c63746..411753992 100644
--- a/Library/Homebrew/cmd/fetch.rb
+++ b/Library/Homebrew/cmd/fetch.rb
@@ -49,8 +49,10 @@ module Homebrew
if fetch_bottle?(f)
begin
fetch_formula(f.bottle)
- rescue Exception => e
- raise if ARGV.homebrew_developer? || e.is_a?(Interrupt)
+ rescue Interrupt
+ raise
+ rescue => e
+ raise if ARGV.homebrew_developer?
fetched_bottle = false
onoe e.message
opoo "Bottle fetch failed: fetching the source."
diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb
index c00087705..ca8f29477 100644
--- a/Library/Homebrew/cmd/install.rb
+++ b/Library/Homebrew/cmd/install.rb
@@ -219,6 +219,7 @@ module Homebrew
end
end
+ return if formulae.empty?
perform_preinstall_checks
formulae.each do |f|
@@ -338,6 +339,7 @@ module Homebrew
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to install f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.
+ return
rescue CannotInstallFormulaError => e
ofail e.message
end
diff --git a/Library/Homebrew/cmd/irb.rb b/Library/Homebrew/cmd/irb.rb
index cba8a5b82..4cd3d4c9e 100644
--- a/Library/Homebrew/cmd/irb.rb
+++ b/Library/Homebrew/cmd/irb.rb
@@ -19,15 +19,13 @@ class String
end
end
-def cask
- $LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib")
- require "hbc"
-end
-
module Homebrew
module_function
def irb
+ $LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib")
+ require "hbc"
+
if ARGV.include? "--examples"
puts "'v8'.f # => instance of the v8 formula"
puts ":hub.f.installed?"
diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb
index f5c4e68ac..436fc1f97 100644
--- a/Library/Homebrew/cmd/list.rb
+++ b/Library/Homebrew/cmd/list.rb
@@ -39,15 +39,7 @@ module Homebrew
filtered_list
elsif ARGV.named.empty?
if ARGV.include? "--full-name"
- full_names = Formula.installed.map(&:full_name).sort do |a, b|
- if a.include?("/") && !b.include?("/")
- 1
- elsif !a.include?("/") && b.include?("/")
- -1
- else
- a <=> b
- end
- end
+ full_names = Formula.installed.map(&:full_name).sort &tap_and_name_comparison
return if full_names.empty?
puts Formatter.columns(full_names)
else
diff --git a/Library/Homebrew/cmd/pin.rb b/Library/Homebrew/cmd/pin.rb
index c5087f6d4..5a14f853c 100644
--- a/Library/Homebrew/cmd/pin.rb
+++ b/Library/Homebrew/cmd/pin.rb
@@ -1,6 +1,7 @@
#: * `pin` <formulae>:
#: Pin the specified <formulae>, preventing them from being upgraded when
-#: issuing the `brew upgrade` command. See also `unpin`.
+#: issuing the `brew upgrade <formulae>` command (but can still be upgraded
+#: as dependencies for other formulae). See also `unpin`.
require "formula"
diff --git a/Library/Homebrew/cmd/postinstall.rb b/Library/Homebrew/cmd/postinstall.rb
index f5d091227..02fd8a5f6 100644
--- a/Library/Homebrew/cmd/postinstall.rb
+++ b/Library/Homebrew/cmd/postinstall.rb
@@ -29,8 +29,6 @@ module Homebrew
args << "--devel"
end
- Sandbox.print_sandbox_message if Sandbox.formula?(formula)
-
Utils.safe_fork do
if Sandbox.formula?(formula)
sandbox = Sandbox.new
diff --git a/Library/Homebrew/cmd/prune.rb b/Library/Homebrew/cmd/prune.rb
index 9fc6dbcd9..7ec2838ba 100644
--- a/Library/Homebrew/cmd/prune.rb
+++ b/Library/Homebrew/cmd/prune.rb
@@ -55,7 +55,7 @@ module Homebrew
else
n, d = ObserverPathnameExtension.counts
print "Pruned #{n} symbolic links "
- print "and #{d} directories " if d > 0
+ print "and #{d} directories " if d.positive?
puts "from #{HOMEBREW_PREFIX}"
end
end
diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb
index 94096d2dd..6727c0b6b 100644
--- a/Library/Homebrew/cmd/reinstall.rb
+++ b/Library/Homebrew/cmd/reinstall.rb
@@ -47,8 +47,8 @@ module Homebrew
fi.install
fi.finish
rescue FormulaInstallationAlreadyAttemptedError
- # next
- rescue Exception
+ return
+ rescue Exception # rubocop:disable Lint/RescueException
ignore_interrupts { restore_backup(keg, keg_was_linked) }
raise
else
diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb
index b2d069744..c01a11c10 100644
--- a/Library/Homebrew/cmd/search.rb
+++ b/Library/Homebrew/cmd/search.rb
@@ -34,38 +34,40 @@ module Homebrew
elsif ARGV.include? "--opensuse"
exec_browser "https://software.opensuse.org/search?q=#{ARGV.next}"
elsif ARGV.include? "--fedora"
- exec_browser "https://admin.fedoraproject.org/pkgdb/packages/%2A#{ARGV.next}%2A/"
+ exec_browser "https://apps.fedoraproject.org/packages/s/#{ARGV.next}"
elsif ARGV.include? "--ubuntu"
- exec_browser "http://packages.ubuntu.com/search?keywords=#{ARGV.next}&searchon=names&suite=all&section=all"
+ exec_browser "https://packages.ubuntu.com/search?keywords=#{ARGV.next}&searchon=names&suite=all&section=all"
elsif ARGV.include? "--desc"
query = ARGV.next
regex = query_regexp(query)
Descriptions.search(regex, :desc).print
elsif ARGV.first =~ HOMEBREW_TAP_FORMULA_REGEX
query = ARGV.first
- user, repo, name = query.split("/", 3)
begin
result = Formulary.factory(query).name
+ results = Array(result)
rescue FormulaUnavailableError
- result = search_tap(user, repo, name)
+ _, _, name = query.split("/", 3)
+ results = search_taps(name)
end
- results = Array(result)
puts Formatter.columns(results) unless results.empty?
else
query = ARGV.first
regex = query_regexp(query)
local_results = search_formulae(regex)
puts Formatter.columns(local_results) unless local_results.empty?
+
tap_results = search_taps(query)
puts Formatter.columns(tap_results) unless tap_results.empty?
if $stdout.tty?
count = local_results.length + tap_results.length
+ ohai "Searching blacklisted, migrated and deleted formulae..."
if reason = Homebrew::MissingFormula.reason(query, silent: true)
- if count > 0
+ if count.positive?
puts
puts "If you meant #{query.inspect} specifically:"
end
@@ -100,10 +102,18 @@ module Homebrew
odie "#{query} is not a valid regex"
end
- def search_taps(query)
+ def search_taps(query, silent: false)
+ return [] if ENV["HOMEBREW_NO_GITHUB_API"]
+
+ # Use stderr to avoid breaking parsed output
+ unless silent
+ $stderr.puts Formatter.headline("Searching taps on GitHub...", color: :blue)
+ end
+
valid_dirnames = ["Formula", "HomebrewFormula", "Casks", "."].freeze
- matches = GitHub.search_code("user:Homebrew", "user:caskroom", "filename:#{query}", "extension:rb")
- [*matches].map do |match|
+ matches = GitHub.search_code(user: ["Homebrew", "caskroom"], filename: query, extension: "rb")
+
+ matches.map do |match|
dirname, filename = File.split(match["path"])
next unless valid_dirnames.include?(dirname)
tap = Tap.fetch(match["repository"]["full_name"])
@@ -113,6 +123,9 @@ module Homebrew
end
def search_formulae(regex)
+ # Use stderr to avoid breaking parsed output
+ $stderr.puts Formatter.headline("Searching local taps...", color: :blue)
+
aliases = Formula.alias_full_names
results = (Formula.full_names + aliases).grep(regex).sort
diff --git a/Library/Homebrew/cmd/style.rb b/Library/Homebrew/cmd/style.rb
index b0f46fadc..58f430a27 100644
--- a/Library/Homebrew/cmd/style.rb
+++ b/Library/Homebrew/cmd/style.rb
@@ -117,12 +117,13 @@ module Homebrew
case output_type
when :print
+ args << "--debug" if ARGV.debug?
args << "--display-cop-names" if ARGV.include? "--display-cop-names"
args << "--format" << "simple" if files
- system(cache_env, "rubocop", *args)
+ system(cache_env, "rubocop", "_#{HOMEBREW_RUBOCOP_VERSION}_", *args)
!$CHILD_STATUS.success?
when :json
- json, _, status = Open3.capture3(cache_env, "rubocop", "--format", "json", *args)
+ json, _, status = Open3.capture3(cache_env, "rubocop", "_#{HOMEBREW_RUBOCOP_VERSION}_", "--format", "json", *args)
# exit status of 1 just means violations were found; other numbers mean
# execution errors.
# exitstatus can also be nil if RuboCop process crashes, e.g. due to
diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb
index af087645d..cb0e0b387 100644
--- a/Library/Homebrew/cmd/tap-info.rb
+++ b/Library/Homebrew/cmd/tap-info.rb
@@ -64,10 +64,10 @@ module Homebrew
if tap.installed?
info += tap.pinned? ? "pinned" : "unpinned"
info += ", private" if tap.private?
- if (formula_count = tap.formula_files.size) > 0
+ if (formula_count = tap.formula_files.size).positive?
info += ", #{Formatter.pluralize(formula_count, "formula")}"
end
- if (command_count = tap.command_files.size) > 0
+ if (command_count = tap.command_files.size).positive?
info += ", #{Formatter.pluralize(command_count, "command")}"
end
info += ", no formulae/commands" if (formula_count + command_count).zero?
diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb
index 2a07c1b2f..fa520e2c5 100644
--- a/Library/Homebrew/cmd/tap.rb
+++ b/Library/Homebrew/cmd/tap.rb
@@ -54,8 +54,7 @@ module Homebrew
quiet: ARGV.quieter?
rescue TapRemoteMismatchError => e
odie e
- rescue TapAlreadyTappedError, TapAlreadyUnshallowError
- # Do nothing.
+ rescue TapAlreadyTappedError, TapAlreadyUnshallowError # rubocop:disable Lint/HandleExceptions
end
end
end
diff --git a/Library/Homebrew/cmd/unlinkapps.rb b/Library/Homebrew/cmd/unlinkapps.rb
index 7cae97e27..56dba3603 100644
--- a/Library/Homebrew/cmd/unlinkapps.rb
+++ b/Library/Homebrew/cmd/unlinkapps.rb
@@ -77,7 +77,7 @@ module Homebrew
def unlinkapps_unlink?(target_app, opts = {})
# Skip non-symlinks and symlinks that don't point into the Homebrew prefix.
app = target_app.readlink.to_s if target_app.symlink?
- return false unless app && app.start_with?(*UNLINKAPPS_PREFIXES)
+ return false unless app&.start_with?(*UNLINKAPPS_PREFIXES)
if opts.fetch(:prune, false)
!File.exist?(app) # Remove only broken symlinks in prune mode.
diff --git a/Library/Homebrew/cmd/unpin.rb b/Library/Homebrew/cmd/unpin.rb
index a669df1ec..e15a156ea 100644
--- a/Library/Homebrew/cmd/unpin.rb
+++ b/Library/Homebrew/cmd/unpin.rb
@@ -1,6 +1,6 @@
#: * `unpin` <formulae>:
-#: Unpin <formulae>, allowing them to be upgraded by `brew upgrade`. See also
-#: `pin`.
+#: Unpin <formulae>, allowing them to be upgraded by `brew upgrade <formulae>`.
+#: See also `pin`.
require "formula"
diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb
index ea915f99c..0974df0b4 100644
--- a/Library/Homebrew/cmd/update-report.rb
+++ b/Library/Homebrew/cmd/update-report.rb
@@ -124,7 +124,7 @@ module Homebrew
return if ENV["HOMEBREW_UPDATE_TEST"]
core_tap = CoreTap.instance
return if core_tap.installed?
- CoreTap.ensure_installed! quiet: false
+ CoreTap.ensure_installed!
revision = core_tap.git_head
ENV["HOMEBREW_UPDATE_BEFORE_HOMEBREW_HOMEBREW_CORE"] = revision
ENV["HOMEBREW_UPDATE_AFTER_HOMEBREW_HOMEBREW_CORE"] = revision
@@ -203,6 +203,7 @@ module Homebrew
end
new_homebrew_repository = Pathname.new "/usr/local/Homebrew"
+ new_homebrew_repository.rmdir_if_possible
if new_homebrew_repository.exist?
ofail <<-EOS.undent
#{new_homebrew_repository} already exists.
@@ -371,7 +372,7 @@ class Reporter
new_version = formula.pkg_version
old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)
next if new_version == old_version
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
end
@report[:M] << tap.formula_file_to_name(src)
@@ -459,7 +460,7 @@ class Reporter
unless Formulary.factory(new_full_name).keg_only?
system HOMEBREW_BREW_FILE, "link", new_full_name, "--overwrite"
end
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
end
next
@@ -520,7 +521,7 @@ class Reporter
begin
f = Formulary.factory(new_full_name)
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
next
end
diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh
index fb6a3459c..3507fa92b 100644
--- a/Library/Homebrew/cmd/update.sh
+++ b/Library/Homebrew/cmd/update.sh
@@ -385,6 +385,12 @@ EOS
if ! git --version >/dev/null 2>&1
then
+ # we need a new enough curl to install git
+ if [[ -n "$HOMEBREW_SYSTEM_CURL_TOO_OLD" &&
+ ! -x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]]
+ then
+ brew install curl
+ fi
# we cannot install brewed git if homebrew/core is unavailable.
[[ -d "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] && brew install git
unset GIT_EXECUTABLE
@@ -564,6 +570,7 @@ EOS
-d "$HOMEBREW_LIBRARY/LinkedKegs" ||
(-n "$HOMEBREW_DEVELOPER" && -z "$HOMEBREW_UPDATE_PREINSTALL") ]]
then
+ unset HOMEBREW_RUBY_PATH
brew update-report "$@"
return $?
elif [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]]
diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb
index 1cdb497cf..f1ce3c7da 100644
--- a/Library/Homebrew/cmd/upgrade.rb
+++ b/Library/Homebrew/cmd/upgrade.rb
@@ -150,6 +150,7 @@ module Homebrew
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to upgrade f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.
+ return
rescue CannotInstallFormulaError => e
ofail e
rescue BuildError => e
diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb
index 24684c3b6..0b09e1bf1 100644
--- a/Library/Homebrew/cmd/uses.rb
+++ b/Library/Homebrew/cmd/uses.rb
@@ -74,12 +74,13 @@ module Homebrew
end
end
- dep_formulae = deps.map do |dep|
+ dep_formulae = deps.flat_map do |dep|
begin
dep.to_formula
rescue
+ []
end
- end.compact
+ end
reqs_by_formula = ([f] + dep_formulae).flat_map do |formula|
formula.requirements.map { |req| [formula, req] }
@@ -118,6 +119,7 @@ module Homebrew
rescue FormulaUnavailableError
# Silently ignore this case as we don't care about things used in
# taps that aren't currently tapped.
+ next
end
end
end
diff --git a/Library/Homebrew/cmd/vendor-install.sh b/Library/Homebrew/cmd/vendor-install.sh
index fe7e26dd4..6d16a297d 100644
--- a/Library/Homebrew/cmd/vendor-install.sh
+++ b/Library/Homebrew/cmd/vendor-install.sh
@@ -13,16 +13,16 @@ if [[ -n "$HOMEBREW_MACOS" ]]
then
if [[ "$HOMEBREW_PROCESSOR" = "Intel" ]]
then
- ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.0.0-p648.leopard_64.bottle.tar.gz"
- ruby_SHA="5c1240abe4be91c9774a0089c2a38a8ccfff87c009e8e5786730c659d5e633f7"
+ ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz"
+ ruby_SHA="34ce9e4c9c1be28db564d744165aa29291426f8a3d2ef806ba4f0b9175aedb2b"
else
ruby_URL=""
ruby_SHA=""
fi
elif [[ -n "$HOMEBREW_LINUX" ]]
then
- ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.0.0-p648.x86_64_linux.bottle.tar.gz"
- ruby_SHA="dbb5118a22a6a75cc77e62544a3d8786d383fab1bdaf8c154951268807357bf0"
+ ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.3.3.x86_64_linux.bottle.tar.gz"
+ ruby_SHA="543c18bd33a300e6c16671437b1e0f17b03bb64e6a485fc15ff7de1eb1a0bc2a"
fi
fetch() {
@@ -45,20 +45,25 @@ fetch() {
curl_args[${#curl_args[*]}]="--progress-bar"
fi
+ if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100600" ]]
+ then
+ curl_args[${#curl_args[*]}]="--insecure"
+ fi
+
temporary_path="$CACHED_LOCATION.incomplete"
mkdir -p "$HOMEBREW_CACHE"
- [[ -n "$HOMEBREW_QUIET" ]] || echo "==> Downloading $VENDOR_URL"
+ [[ -n "$HOMEBREW_QUIET" ]] || echo "==> Downloading $VENDOR_URL" >&2
if [[ -f "$CACHED_LOCATION" ]]
then
- [[ -n "$HOMEBREW_QUIET" ]] || echo "Already downloaded: $CACHED_LOCATION"
+ [[ -n "$HOMEBREW_QUIET" ]] || echo "Already downloaded: $CACHED_LOCATION" >&2
else
if [[ -f "$temporary_path" ]]
then
"$HOMEBREW_CURL" "${curl_args[@]}" -C - "$VENDOR_URL" -o "$temporary_path"
if [[ $? -eq 33 ]]
then
- [[ -n "$HOMEBREW_QUIET" ]] || echo "Trying a full download"
+ [[ -n "$HOMEBREW_QUIET" ]] || echo "Trying a full download" >&2
rm -f "$temporary_path"
"$HOMEBREW_CURL" "${curl_args[@]}" "$VENDOR_URL" -o "$temporary_path"
fi
@@ -135,7 +140,7 @@ install() {
fi
safe_cd "$VENDOR_DIR"
- [[ -n "$HOMEBREW_QUIET" ]] || echo "==> Unpacking $(basename "$VENDOR_URL")"
+ [[ -n "$HOMEBREW_QUIET" ]] || echo "==> Pouring $(basename "$VENDOR_URL")" >&2
tar "$tar_args" "$CACHED_LOCATION"
safe_cd "$VENDOR_DIR/portable-$VENDOR_NAME"
diff --git a/Library/Homebrew/compat/ENV/shared.rb b/Library/Homebrew/compat/ENV/shared.rb
index 200e7b132..c700b1e00 100644
--- a/Library/Homebrew/compat/ENV/shared.rb
+++ b/Library/Homebrew/compat/ENV/shared.rb
@@ -3,4 +3,8 @@ module SharedEnvExtension
odeprecated "ENV.j1", "ENV.deparallelize"
deparallelize
end
+
+ def java_cache
+ # odeprecated "ENV.java_cache"
+ end
end
diff --git a/Library/Homebrew/compat/formula_specialties.rb b/Library/Homebrew/compat/formula_specialties.rb
index ec5e91ce8..78966625e 100644
--- a/Library/Homebrew/compat/formula_specialties.rb
+++ b/Library/Homebrew/compat/formula_specialties.rb
@@ -16,7 +16,7 @@ end
# This formula serves as the base class for several very similar
# formulae for Amazon Web Services related tools.
class AmazonWebServicesFormula < Formula
- # Use this method to peform a standard install for Java-based tools,
+ # Use this method to perform a standard install for Java-based tools,
# keeping the .jars out of HOMEBREW_PREFIX/lib
def install
odeprecated "AmazonWebServicesFormula#install", "Formula#install"
diff --git a/Library/Homebrew/constants.rb b/Library/Homebrew/constants.rb
index 23be70bcc..b122946c8 100644
--- a/Library/Homebrew/constants.rb
+++ b/Library/Homebrew/constants.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# RuboCop version used for `brew style` and `brew cask style`
-HOMEBREW_RUBOCOP_VERSION = "0.49.1".freeze
-HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.13.1".freeze # has to be updated when RuboCop version changes
+HOMEBREW_RUBOCOP_VERSION = "0.50.0"
+HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.14.2" # has to be updated when RuboCop version changes
diff --git a/Library/Homebrew/debrew.rb b/Library/Homebrew/debrew.rb
index c2662c9ee..6206eb8a2 100644
--- a/Library/Homebrew/debrew.rb
+++ b/Library/Homebrew/debrew.rb
@@ -9,7 +9,7 @@ module Debrew
module Raise
def raise(*)
super
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
e.extend(Ignorable)
super(e) unless Debrew.debug(e) == :ignore
end
@@ -57,7 +57,7 @@ module Debrew
input.chomp!
i = input.to_i
- if i > 0
+ if i.positive?
choice = menu.entries[i - 1]
else
possible = menu.entries.find_all { |e| e.name.start_with?(input) }
@@ -92,7 +92,7 @@ module Debrew
yield
rescue SystemExit
original_raise
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
debug(e)
ensure
@active = false
@@ -119,7 +119,7 @@ module Debrew
if e.is_a?(Ignorable)
menu.choice(:irb) do
puts "When you exit this IRB session, execution will continue."
- set_trace_func proc { |event, _, _, id, binding, klass|
+ set_trace_func proc { |event, _, _, id, binding, klass| # rubocop:disable Metrics/ParameterLists
if klass == Raise && id == :raise && event == "return"
set_trace_func(nil)
synchronize { IRB.start_within(binding) }
diff --git a/Library/Homebrew/debrew/irb.rb b/Library/Homebrew/debrew/irb.rb
index f97403782..eeb3758a9 100644
--- a/Library/Homebrew/debrew/irb.rb
+++ b/Library/Homebrew/debrew/irb.rb
@@ -4,8 +4,7 @@ module IRB
@setup_done = false
extend Module.new {
- def parse_opts
- end
+ def parse_opts; end
def start_within(binding)
unless @setup_done
@@ -16,7 +15,7 @@ module IRB
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
- @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
+ @CONF[:IRB_RC]&.call(irb.context)
@CONF[:MAIN_CONTEXT] = irb.context
trap("SIGINT") do
diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb
index d7d5ec59c..7f0e7fbff 100644
--- a/Library/Homebrew/dependency.rb
+++ b/Library/Homebrew/dependency.rb
@@ -51,7 +51,7 @@ class Dependency
end
def modify_build_environment
- env_proc.call unless env_proc.nil?
+ env_proc&.call
end
def inspect
@@ -64,7 +64,7 @@ class Dependency
end
def self._load(marshaled)
- new(*Marshal.load(marshaled))
+ new(*Marshal.load(marshaled)) # rubocop:disable Security/MarshalLoad
end
class << self
diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb
index fff80a28c..f855669e0 100644
--- a/Library/Homebrew/dependency_collector.rb
+++ b/Library/Homebrew/dependency_collector.rb
@@ -4,6 +4,7 @@ require "ld64_dependency"
require "requirement"
require "requirements"
require "set"
+require "extend/cachable"
## A dependency is a formula that another formula needs to install.
## A requirement is something other than a formula that another formula
@@ -16,17 +17,13 @@ require "set"
# This class is used by `depends_on` in the formula DSL to turn dependency
# specifications into the proper kinds of dependencies and requirements.
class DependencyCollector
+ extend Cachable
+
# Define the languages that we can handle as external dependencies.
LANGUAGE_MODULES = Set[
:lua, :lua51, :perl, :python, :python3, :ruby
].freeze
- CACHE = {}
-
- def self.clear_cache
- CACHE.clear
- end
-
attr_reader :deps, :requirements
def initialize
@@ -45,7 +42,7 @@ class DependencyCollector
end
def fetch(spec)
- CACHE.fetch(cache_key(spec)) { |key| CACHE[key] = build(spec) }
+ self.class.cache.fetch(cache_key(spec)) { |key| self.class.cache[key] = build(spec) }
end
def cache_key(spec)
diff --git a/Library/Homebrew/descriptions.rb b/Library/Homebrew/descriptions.rb
index ac1d68216..bc1982673 100644
--- a/Library/Homebrew/descriptions.rb
+++ b/Library/Homebrew/descriptions.rb
@@ -78,10 +78,10 @@ class Descriptions
formula_names.each do |name|
begin
- desc = Formulary.factory(name).desc
+ @cache[name] = Formulary.factory(name).desc
rescue FormulaUnavailableError, *FormulaVersions::IGNORED_EXCEPTIONS
+ @cache.delete(name)
end
- @cache[name] = desc
end
save_cache if options[:save]
end
diff --git a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb b/Library/Homebrew/dev-cmd/aspell-dictionaries.rb
index 955e41b01..ab0e66d2b 100644
--- a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb
+++ b/Library/Homebrew/dev-cmd/aspell-dictionaries.rb
@@ -27,13 +27,12 @@ module Homebrew
end
end
- languages.inject([]) do |resources, (lang, path)|
+ languages.each do |lang, path|
r = Resource.new(lang)
r.owner = Formulary.factory("aspell")
r.url "#{dict_url}/#{path}"
r.mirror "#{dict_mirror}/#{path}"
- resources << r
- end.each(&:fetch).each do |r|
+ r.fetch
puts <<-EOS
option "with-lang-#{r.name}", "Install #{r.name} dictionary"
resource "#{r.name}" do
diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb
index f8236e6a6..b58672043 100644
--- a/Library/Homebrew/dev-cmd/audit.rb
+++ b/Library/Homebrew/dev-cmd/audit.rb
@@ -53,7 +53,8 @@ module Homebrew
module_function
def audit
- Homebrew.inject_dump_stats!(FormulaAuditor, /^audit_/) if ARGV.switch? "D"
+ inject_dump_stats!(FormulaAuditor, /^audit_/) if ARGV.switch? "D"
+ Homebrew.auditing = true
formula_count = 0
problem_count = 0
@@ -201,19 +202,24 @@ class FormulaAuditor
@specs = %w[stable devel head].map { |s| formula.send(s) }.compact
end
- def self.check_http_content(url, name, user_agents: [:default])
+ def self.check_http_content(url, user_agents: [:default], check_content: false, strict: false, require_http: false)
return unless url.start_with? "http"
details = nil
user_agent = nil
- hash_needed = url.start_with?("http:") && name != "curl"
+ hash_needed = url.start_with?("http:") && !require_http
user_agents.each do |ua|
details = http_content_headers_and_checksum(url, hash_needed: hash_needed, 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]
+ # Hack around https://github.com/Homebrew/brew/issues/3199
+ return if MacOS.version == :el_capitan
+ return "The URL #{url} is not reachable"
+ end
+
unless details[:status].start_with? "2"
return "The URL #{url} is not reachable (HTTP status code #{details[:status]})"
end
@@ -236,18 +242,40 @@ class FormulaAuditor
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"
+ if etag_match || content_length_match || file_match
+ return "The URL #{url} should use HTTPS rather than HTTP"
+ end
+
+ return unless check_content
+
+ no_protocol_file_contents = %r{https?:\\?/\\?/}
+ details[:file] = details[:file].gsub(no_protocol_file_contents, "/")
+ secure_details[:file] = secure_details[:file].gsub(no_protocol_file_contents, "/")
+
+ # Check for the same content after removing all protocols
+ if details[:file] == secure_details[:file]
+ return "The URL #{url} should use HTTPS rather than HTTP"
+ end
+
+ return unless strict
+
+ # Same size, different content after normalization
+ # (typical causes: Generated ID, Timestamp, Unix time)
+ if details[:file].length == secure_details[:file].length
+ return "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser."
+ end
+
+ lenratio = (100 * secure_details[:file].length / details[:file].length).to_i
+ return unless (90..110).cover?(lenratio)
+ "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser."
end
def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default)
max_time = hash_needed ? "600" : "25"
- args = curl_args(
- extra_args: ["--connect-timeout", "15", "--include", "--max-time", max_time, url],
- show_output: true,
- user_agent: user_agent,
+ output, = curl_output(
+ "--connect-timeout", "15", "--include", "--max-time", max_time, "--location", url,
+ 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")
@@ -262,6 +290,7 @@ class FormulaAuditor
etag: headers[%r{ETag: ([wW]\/)?"(([^"]|\\")*)"}, 2],
content_length: headers[/Content-Length: (\d+)/, 1],
file_hash: output_hash,
+ file: output,
}
end
@@ -329,7 +358,8 @@ class FormulaAuditor
end
valid_alias_names = [alias_name_major, alias_name_major_minor]
- if formula.tap && !formula.tap.core_tap?
+ unless formula.tap&.core_tap?
+ versioned_aliases.map! { |a| "#{formula.tap}/#{a}" }
valid_alias_names.map! { |a| "#{formula.tap}/#{a}" }
end
@@ -357,31 +387,17 @@ class FormulaAuditor
end
end
- def audit_class
- if @strict
- unless formula.test_defined?
- problem "A `test do` test block should be added"
- end
- end
-
- classes = %w[GithubGistFormula ScriptFileFormula AmazonWebServicesFormula]
- klass = classes.find do |c|
- Object.const_defined?(c) && formula.class < Object.const_get(c)
- end
-
- problem "#{klass} is deprecated, use Formula instead" if klass
+ def self.aliases
+ # core aliases + tap alias names + tap alias full name
+ @aliases ||= Formula.aliases + Formula.tap_aliases
end
- # core aliases + tap alias names + tap alias full name
- @@aliases ||= Formula.aliases + Formula.tap_aliases
-
def audit_formula_name
return unless @strict
# skip for non-official taps
return if formula.tap.nil? || !formula.tap.official?
name = formula.name
- full_name = formula.full_name
if Homebrew::MissingFormula.blacklisted_reason(name)
problem "'#{name}' is blacklisted."
@@ -397,33 +413,10 @@ class FormulaAuditor
return
end
- if !formula.core_formula? && Formula.core_names.include?(name)
- problem "Formula name conflicts with existing core formula."
- return
- end
-
- @@local_official_taps_name_map ||= Tap.select(&:official?).flat_map(&:formula_names)
- .each_with_object({}) do |tap_formula_full_name, name_map|
- tap_formula_name = tap_formula_full_name.split("/").last
- name_map[tap_formula_name] ||= []
- name_map[tap_formula_name] << tap_formula_full_name
- name_map
- end
+ return if formula.core_formula?
+ return unless Formula.core_names.include?(name)
- same_name_tap_formulae = @@local_official_taps_name_map[name] || []
-
- if @online
- Homebrew.search_taps(name).each do |tap_formula_full_name|
- tap_formula_name = tap_formula_full_name.split("/").last
- next if tap_formula_name != name
- same_name_tap_formulae << tap_formula_full_name
- end
- end
-
- same_name_tap_formulae.delete(full_name)
-
- return if same_name_tap_formulae.empty?
- problem "Formula name conflicts with #{same_name_tap_formulae.join ", "}"
+ problem "Formula name conflicts with existing core formula."
end
def audit_deps
@@ -451,7 +444,7 @@ class FormulaAuditor
problem "Dependency '#{dep.name}' was renamed; use new name '#{dep_f.name}'."
end
- if @@aliases.include?(dep.name) &&
+ if self.class.aliases.include?(dep.name) &&
(dep_f.core_formula? || !dep_f.versioned_formula?)
problem "Dependency '#{dep.name}' is an alias; use the canonical name '#{dep.to_formula.full_name}'."
end
@@ -462,16 +455,16 @@ class FormulaAuditor
problem "Dependency '#{dep.name}' may be unnecessary as it is provided by macOS; try to build this formula without it."
end
- dep.options.reject do |opt|
- next true if dep_f.option_defined?(opt)
- dep_f.requirements.detect do |r|
+ dep.options.each do |opt|
+ next if dep_f.option_defined?(opt)
+ next if dep_f.requirements.detect do |r|
if r.recommended?
opt.name == "with-#{r.name}"
elsif r.optional?
opt.name == "without-#{r.name}"
end
end
- end.each do |opt|
+
problem "Dependency #{dep} does not define option #{opt.name.inspect}"
end
@@ -564,10 +557,11 @@ class FormulaAuditor
return unless @online
- return unless DevelopmentTools.curl_handles_most_https_homepages?
+ return unless DevelopmentTools.curl_handles_most_https_certificates?
if http_content_problem = FormulaAuditor.check_http_content(homepage,
- formula.name,
- user_agents: [:browser, :default])
+ user_agents: [:browser, :default],
+ check_content: true,
+ strict: @strict)
problem http_content_problem
end
end
@@ -598,7 +592,8 @@ class FormulaAuditor
return if metadata.nil?
problem "GitHub fork (not canonical repository)" if metadata["fork"]
- if (metadata["forks_count"] < 20) && (metadata["subscribers_count"] < 20) &&
+ if formula&.tap&.core_tap? &&
+ (metadata["forks_count"] < 20) && (metadata["subscribers_count"] < 20) &&
(metadata["stargazers_count"] < 50)
problem "GitHub repository not notable enough (<20 forks, <20 watchers and <50 stars)"
end
@@ -617,13 +612,14 @@ class FormulaAuditor
end
%w[Stable Devel HEAD].each do |name|
- next unless spec = formula.send(name.downcase)
+ spec_name = name.downcase.to_sym
+ next unless spec = formula.send(spec_name)
- ra = ResourceAuditor.new(spec, online: @online, strict: @strict).audit
+ ra = ResourceAuditor.new(spec, spec_name, 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, strict: @strict).audit
+ ra = ResourceAuditor.new(resource, spec_name, online: @online, strict: @strict).audit
problems.concat ra.problems.map { |problem|
"#{name} resource #{resource.name.inspect}: #{problem}"
}
@@ -688,7 +684,7 @@ class FormulaAuditor
end
stable = formula.stable
- case stable && stable.url
+ case stable&.url
when /[\d\._-](alpha|beta|rc\d)/
matched = Regexp.last_match(1)
version_prefix = stable.version.to_s.sub(/\d+$/, "")
@@ -855,7 +851,7 @@ class FormulaAuditor
def audit_reverse_migration
# Only enforce for new formula being re-added to core and official taps
return unless @strict
- return unless formula.tap && formula.tap.official?
+ return unless formula.tap&.official?
return unless formula.tap.tap_migrations.key?(formula.name)
problem <<-EOS.undent
@@ -918,10 +914,10 @@ class FormulaAuditor
end
class ResourceAuditor
- attr_reader :problems
- attr_reader :version, :checksum, :using, :specs, :url, :mirrors, :name
+ attr_reader :name, :version, :checksum, :url, :mirrors, :using, :specs, :owner
+ attr_reader :spec_name, :problems
- def initialize(resource, options = {})
+ def initialize(resource, spec_name, options = {})
@name = resource.name
@version = resource.version
@checksum = resource.checksum
@@ -929,9 +925,11 @@ class ResourceAuditor
@mirrors = resource.mirrors
@using = resource.using
@specs = resource.specs
- @online = options[:online]
- @strict = options[:strict]
- @problems = []
+ @owner = resource.owner
+ @spec_name = spec_name
+ @online = options[:online]
+ @strict = options[:strict]
+ @problems = []
end
def audit
@@ -1005,11 +1003,29 @@ class ResourceAuditor
problem "Redundant :using value in URL"
end
+ def self.curl_openssl_and_deps
+ @curl_openssl_and_deps ||= begin
+ formulae_names = ["curl", "openssl"]
+ formulae_names += formulae_names.flat_map do |f|
+ Formula[f].recursive_dependencies.map(&:name)
+ end
+ formulae_names.uniq
+ rescue FormulaUnavailableError
+ []
+ end
+ end
+
def audit_urls
urls = [url] + mirrors
- if name == "curl" && !urls.find { |u| u.start_with?("http://") }
- problem "should always include at least one HTTP url"
+ curl_openssl_or_deps = ResourceAuditor.curl_openssl_and_deps.include?(owner.name)
+
+ if spec_name == :stable && curl_openssl_or_deps
+ problem "should not use xz tarballs" if url.end_with?(".xz")
+
+ unless urls.find { |u| u.start_with?("http://") }
+ problem "should always include at least one HTTP mirror"
+ end
end
return unless @online
@@ -1021,7 +1037,7 @@ class ResourceAuditor
# A `brew mirror`'ed URL is usually not yet reachable at the time of
# pull request.
next if url =~ %r{^https://dl.bintray.com/homebrew/mirror/}
- if http_content_problem = FormulaAuditor.check_http_content(url, name)
+ if http_content_problem = FormulaAuditor.check_http_content(url, require_http: curl_openssl_or_deps)
problem http_content_problem
end
elsif strategy <= GitDownloadStrategy
@@ -1030,6 +1046,7 @@ class ResourceAuditor
end
elsif strategy <= SubversionDownloadStrategy
next unless DevelopmentTools.subversion_handles_most_https_certificates?
+ next unless Utils.svn_available?
unless Utils.svn_remote_exists url
problem "The URL #{url} is not a valid svn URL"
end
diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb
index d8aefc4c0..fb862c773 100644
--- a/Library/Homebrew/dev-cmd/bottle.rb
+++ b/Library/Homebrew/dev-cmd/bottle.rb
@@ -47,7 +47,7 @@ BOTTLE_ERB = <<-EOS.freeze
<% elsif cellar != BottleSpecification::DEFAULT_CELLAR %>
cellar "<%= cellar %>"
<% end %>
- <% if rebuild > 0 %>
+ <% if rebuild.positive? %>
rebuild <%= rebuild %>
<% end %>
<% checksums.each do |checksum_type, checksum_values| %>
@@ -75,7 +75,7 @@ module Homebrew
@put_filenames ||= []
- return if @put_filenames.include? filename
+ return if @put_filenames.include?(filename)
puts Formatter.error(filename.to_s)
@put_filenames << filename
@@ -84,8 +84,7 @@ module Homebrew
result = false
keg.each_unique_file_matching(string) do |file|
- # skip document file.
- next if Metafiles::EXTENSIONS.include? file.extname
+ next if Metafiles::EXTENSIONS.include?(file.extname) # Skip document files.
linked_libraries = Keg.file_linked_libraries(file, string)
result ||= !linked_libraries.empty?
@@ -156,9 +155,7 @@ module Homebrew
return ofail "Formula not installed or up-to-date: #{f.full_name}"
end
- tap = f.tap
-
- unless tap
+ unless tap = f.tap
unless ARGV.include?("--force-core-tap")
return ofail "Formula not from core or any taps: #{f.full_name}"
end
@@ -186,7 +183,7 @@ module Homebrew
ohai "Determining #{f.full_name} bottle rebuild..."
versions = FormulaVersions.new(f)
rebuilds = versions.bottle_version_map("origin/master")[f.pkg_version]
- rebuilds.pop if rebuilds.last.to_i > 0
+ rebuilds.pop if rebuilds.last.to_i.positive?
rebuild = rebuilds.empty? ? 0 : rebuilds.max.to_i + 1
end
@@ -283,7 +280,7 @@ module Homebrew
raise
ensure
ignore_interrupts do
- original_tab.write if original_tab
+ original_tab&.write
unless ARGV.include? "--skip-relocation"
keg.replace_placeholders_with_locations changed_files
end
diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
index 1c56749a3..87d8274cc 100644
--- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb
+++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
@@ -89,7 +89,8 @@ module Homebrew
def check_for_duplicate_pull_requests(formula)
pull_requests = fetch_pull_requests(formula)
- return unless pull_requests && !pull_requests.empty?
+ return unless pull_requests
+ return if pull_requests.empty?
duplicates_message = <<-EOS.undent
These open pull requests may be duplicates:
#{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
@@ -124,7 +125,7 @@ module Homebrew
Formula.each do |f|
if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url)
guesses << f
- elsif f.stable && f.stable.url && f.stable.url.match(base_url)
+ elsif f.stable&.url && f.stable.url.match(base_url)
guesses << f
end
end
@@ -176,7 +177,10 @@ module Homebrew
rsrc.version = forced_version if forced_version
odie "No version specified!" unless rsrc.version
rsrc_path = rsrc.fetch
- if Utils.popen_read("/usr/bin/tar", "-tf", rsrc_path) =~ %r{/.*\.}
+ gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar"
+ gnu_tar_gtar = gnu_tar_gtar_path if gnu_tar_gtar_path.executable?
+ tar = which("gtar") || gnu_tar_gtar || which("tar")
+ if Utils.popen_read(tar, "-tf", rsrc_path) =~ %r{/.*\.}
new_hash = rsrc_path.sha256
elsif new_url.include? ".tar"
odie "#{formula}: no url/#{hash_type} specified!"
@@ -293,9 +297,7 @@ module Homebrew
ohai "git fetch --unshallow origin" if shallow
ohai "git checkout --no-track -b #{branch} origin/master"
ohai "git commit --no-edit --verbose --message='#{formula.name} #{new_formula_version}#{devel_message}' -- #{formula.path}"
- ohai "hub fork --no-remote"
- ohai "hub fork"
- ohai "hub fork (to read $HUB_REMOTE)"
+ ohai "hub fork # read $HUB_REMOTE"
ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}"
ohai "hub pull-request --browse -m '#{formula.name} #{new_formula_version}#{devel_message}'"
ohai "git checkout -"
@@ -305,9 +307,9 @@ module Homebrew
safe_system "git", "commit", "--no-edit", "--verbose",
"--message=#{formula.name} #{new_formula_version}#{devel_message}",
"--", formula.path
- safe_system "hub", "fork", "--no-remote"
- quiet_system "hub", "fork"
- remote = Utils.popen_read("hub fork 2>&1")[/fatal: remote (.+) already exists\./, 1]
+ remote = Utils.popen_read("hub fork 2>&1")[/remote:? (\S+)/, 1]
+ # repeat for hub 2.2 backwards compatibility:
+ remote = Utils.popen_read("hub fork 2>&1")[/remote:? (\S+)/, 1] if remote.to_s.empty?
odie "cannot get remote from 'hub'!" if remote.to_s.empty?
safe_system "git", "push", "--set-upstream", remote, "#{branch}:#{branch}"
pr_message = <<-EOS.undent
diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb
index 472bb7c2b..b2bb3c8c3 100644
--- a/Library/Homebrew/dev-cmd/man.rb
+++ b/Library/Homebrew/dev-cmd/man.rb
@@ -48,12 +48,9 @@ module Homebrew
def path_glob_commands(glob)
Pathname.glob(glob)
.sort_by { |source_file| sort_key_for_path(source_file) }
- .map do |source_file|
- source_file.read.lines
- .grep(/^#:/)
- .map { |line| line.slice(2..-1) }
- .join
- end.reject { |s| s.strip.empty? || s.include?("@hide_from_man_page") }
+ .map(&:read).map(&:lines)
+ .map { |lines| lines.grep(/^#:/).map { |line| line.slice(2..-1) }.join }
+ .reject { |s| s.strip.empty? || s.include?("@hide_from_man_page") }
end
def build_man_page
diff --git a/Library/Homebrew/dev-cmd/mirror.rb b/Library/Homebrew/dev-cmd/mirror.rb
index e2492203d..6445bc34c 100644
--- a/Library/Homebrew/dev-cmd/mirror.rb
+++ b/Library/Homebrew/dev-cmd/mirror.rb
@@ -25,9 +25,9 @@ module Homebrew
"public_download_numbers": true,
"public_stats": true}
EOS
- curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}",
- "-H", "Content-Type: application/json",
- "-d", package_blob, bintray_repo_url
+ curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
+ "--header", "Content-Type: application/json",
+ "--data", package_blob, bintray_repo_url
puts
end
@@ -40,8 +40,8 @@ module Homebrew
content_url = "https://api.bintray.com/content/homebrew/mirror"
content_url += "/#{bintray_package}/#{f.pkg_version}/#{filename}"
content_url += "?publish=1"
- curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}",
- "-T", download, content_url
+ curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
+ "--upload-file", download, content_url
puts
ohai "Mirrored #{filename}!"
end
diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb
index 9681bb2bc..8cb270303 100644
--- a/Library/Homebrew/dev-cmd/pull.rb
+++ b/Library/Homebrew/dev-cmd/pull.rb
@@ -69,13 +69,13 @@ module Homebrew
tap = nil
ARGV.named.each do |arg|
- if arg.to_i > 0
+ if arg.to_i.positive?
issue = arg
url = "https://github.com/Homebrew/homebrew-core/pull/#{arg}"
tap = CoreTap.instance
elsif (testing_match = arg.match %r{/job/Homebrew.*Testing/(\d+)/})
tap = ARGV.value("tap")
- tap = if tap && tap.start_with?("homebrew/")
+ tap = if tap&.start_with?("homebrew/")
Tap.fetch("homebrew", tap.strip_prefix("homebrew/"))
elsif tap
odie "Tap option did not start with \"homebrew/\": #{tap}"
@@ -154,8 +154,8 @@ module Homebrew
begin
f = Formula[name]
- # Make sure we catch syntax errors.
- rescue Exception
+ rescue Exception # rubocop:disable Lint/RescueException
+ # Make sure we catch syntax errors.
next
end
@@ -228,7 +228,7 @@ module Homebrew
"https://github.com/BrewTestBot/homebrew-#{tap.repo}/compare/homebrew:master...pr-#{issue}"
end
- curl "--silent", "--fail", "-o", "/dev/null", "-I", bottle_commit_url
+ curl "--silent", "--fail", "--output", "/dev/null", "--head", bottle_commit_url
safe_system "git", "checkout", "--quiet", "-B", bottle_branch, orig_revision
pull_patch bottle_commit_url, "bottle commit"
@@ -303,7 +303,7 @@ module Homebrew
extra_msg = @description ? "(#{@description})" : nil
ohai "Fetching patch #{extra_msg}"
puts "Patch: #{patch_url}"
- curl patch_url, "-s", "-o", patchpath
+ curl_download patch_url, to: patchpath
end
def apply_patch
@@ -350,7 +350,7 @@ module Homebrew
files << Regexp.last_match(1) if line =~ %r{^\+\+\+ b/(.*)}
end
files.each do |file|
- if tap && tap.formula_file?(file)
+ if tap&.formula_file?(file)
formula_name = File.basename(file, ".rb")
formulae << formula_name unless formulae.include?(formula_name)
else
@@ -433,10 +433,10 @@ module Homebrew
end
version = info.pkg_version
ohai "Publishing on Bintray: #{package} #{version}"
- curl "-w", '\n', "--silent", "--fail",
- "-u#{creds[:user]}:#{creds[:key]}", "-X", "POST",
- "-H", "Content-Type: application/json",
- "-d", '{"publish_wait_for_secs": 0}',
+ curl "--write-out", '\n', "--silent", "--fail",
+ "--user", "#{creds[:user]}:#{creds[:key]}", "--request", "POST",
+ "--header", "Content-Type: application/json",
+ "--data", '{"publish_wait_for_secs": 0}',
"https://api.bintray.com/content/homebrew/#{repo}/#{package}/#{version}/publish"
true
rescue => e
@@ -587,7 +587,7 @@ module Homebrew
# We're in the cache; make sure to force re-download
loop do
begin
- curl url, "-o", filename
+ curl_download url, continue_at: 0, to: filename
break
rescue
if retry_count >= max_curl_retries
@@ -606,7 +606,7 @@ module Homebrew
end
def check_bintray_mirror(name, url)
- headers = curl_output("--connect-timeout", "15", "--head", url)[0]
+ headers, = curl_output("--connect-timeout", "15", "--location", "--head", url)
status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first
return if status_code.start_with?("2")
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."
diff --git a/Library/Homebrew/dev-cmd/release-notes.rb b/Library/Homebrew/dev-cmd/release-notes.rb
index e578869bf..496023956 100644
--- a/Library/Homebrew/dev-cmd/release-notes.rb
+++ b/Library/Homebrew/dev-cmd/release-notes.rb
@@ -10,10 +10,8 @@ module Homebrew
def release_notes
previous_tag = ARGV.named.first
- unless previous_tag
- previous_tag = Utils.popen_read("git tag --list --sort=-version:refname")
+ previous_tag ||= Utils.popen_read("git tag --list --sort=-version:refname")
.lines.first.chomp
- end
odie "Could not find any previous tags!" unless previous_tag
end_ref = ARGV.named[1] || "origin/master"
diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb
index c678171ac..6622a8c25 100644
--- a/Library/Homebrew/dev-cmd/test.rb
+++ b/Library/Homebrew/dev-cmd/test.rb
@@ -65,8 +65,6 @@ module Homebrew
args << "--devel"
end
- Sandbox.print_sandbox_message if Sandbox.test?
-
Utils.safe_fork do
if Sandbox.test?
sandbox = Sandbox.new
@@ -86,7 +84,7 @@ module Homebrew
rescue ::Test::Unit::AssertionFailedError => e
ofail "#{f.full_name}: failed"
puts e.message
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
ofail "#{f.full_name}: failed"
puts e, e.backtrace
ensure
diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb
index aa7fe6a92..1f1cdbeed 100644
--- a/Library/Homebrew/dev-cmd/update-test.rb
+++ b/Library/Homebrew/dev-cmd/update-test.rb
@@ -81,7 +81,7 @@ module Homebrew
safe_system "git", "reset", "--hard", start_commit
# update ENV["PATH"]
- ENV["PATH"] = "#{curdir}/bin:/usr/local/bin:/usr/bin:/bin"
+ ENV["PATH"] = PATH.new(ENV["PATH"]).prepend(curdir/"bin")
# run brew update
oh1 "Running brew update..."
diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb
index 996dea87c..b7787d849 100644
--- a/Library/Homebrew/development_tools.rb
+++ b/Library/Homebrew/development_tools.rb
@@ -114,7 +114,7 @@ class DevelopmentTools
@non_apple_gcc_version = {}
end
- def curl_handles_most_https_homepages?
+ def curl_handles_most_https_certificates?
true
end
diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb
index ceb6ad4d1..3edf31012 100644
--- a/Library/Homebrew/diagnostic.rb
+++ b/Library/Homebrew/diagnostic.rb
@@ -151,8 +151,10 @@ module Homebrew
return unless File.directory?(dir)
files = Dir.chdir(dir) do
- Dir[pattern].select { |f| File.file?(f) && !File.symlink?(f) } - Dir.glob(white_list)
- end.map { |file| File.join(dir, file) }
+ (Dir.glob(pattern) - Dir.glob(white_list))
+ .select { |f| File.file?(f) && !File.symlink?(f) }
+ .map { |f| File.join(dir, f) }
+ end
return if files.empty?
inject_file_list(files, message)
@@ -427,15 +429,15 @@ module Homebrew
end
def check_user_path_1
- $seen_prefix_bin = false
- $seen_prefix_sbin = false
+ @seen_prefix_bin = false
+ @seen_prefix_sbin = false
message = ""
paths(ENV["HOMEBREW_PATH"]).each do |p|
case p
when "/usr/bin"
- unless $seen_prefix_bin
+ unless @seen_prefix_bin
# only show the doctor message if there are any conflicts
# rationale: a default install should not trigger any brew doctor messages
conflicts = Dir["#{HOMEBREW_PREFIX}/bin/*"]
@@ -458,9 +460,9 @@ module Homebrew
end
end
when "#{HOMEBREW_PREFIX}/bin"
- $seen_prefix_bin = true
+ @seen_prefix_bin = true
when "#{HOMEBREW_PREFIX}/sbin"
- $seen_prefix_sbin = true
+ @seen_prefix_sbin = true
end
end
@@ -468,7 +470,7 @@ module Homebrew
end
def check_user_path_2
- return if $seen_prefix_bin
+ return if @seen_prefix_bin
<<-EOS.undent
Homebrew's bin was not found in your PATH.
@@ -478,7 +480,7 @@ module Homebrew
end
def check_user_path_3
- return if $seen_prefix_sbin
+ return if @seen_prefix_sbin
# Don't complain about sbin not being in the path if it doesn't exist
sbin = HOMEBREW_PREFIX/"sbin"
@@ -522,7 +524,7 @@ module Homebrew
homebrew_owned = @found.all? do |path|
Pathname.new(path).realpath.to_s.start_with? "#{HOMEBREW_CELLAR}/gettext"
end
- return if gettext && gettext.linked_keg.directory? && homebrew_owned
+ return if gettext&.linked_keg&.directory? && homebrew_owned
inject_file_list @found, <<-EOS.undent
gettext files detected at a system prefix.
@@ -540,7 +542,7 @@ module Homebrew
rescue
nil
end
- if libiconv && libiconv.linked_keg.directory?
+ if libiconv&.linked_keg&.directory?
unless libiconv.keg_only?
<<-EOS.undent
A libiconv formula is installed and linked.
@@ -952,6 +954,7 @@ module Homebrew
Putting non-prefixed coreutils in your path can cause gmp builds to fail.
EOS
rescue FormulaUnavailableError
+ return
end
def check_for_non_prefixed_findutils
@@ -966,6 +969,7 @@ module Homebrew
Putting non-prefixed findutils in your path can cause python builds to fail.
EOS
rescue FormulaUnavailableError
+ return
end
def check_for_pydistutils_cfg_in_home
diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb
index 717334714..e69a56ddf 100644
--- a/Library/Homebrew/download_strategy.rb
+++ b/Library/Homebrew/download_strategy.rb
@@ -18,8 +18,7 @@ class AbstractDownloadStrategy
end
# Download and cache the resource as {#cached_location}.
- def fetch
- end
+ def fetch; end
# Suppress output
def shutup!
@@ -37,13 +36,11 @@ class AbstractDownloadStrategy
# Unpack {#cached_location} into the current working directory, and possibly
# chdir into the newly-unpacked directory.
# Unlike {Resource#stage}, this does not take a block.
- def stage
- end
+ def stage; end
# @!attribute [r] cached_location
# The path to the cached file or directory associated with the resource.
- def cached_location
- end
+ def cached_location; end
# @!attribute [r]
# return most recent modified time for all files in the current working directory after stage.
@@ -204,14 +201,11 @@ class VCSDownloadStrategy < AbstractDownloadStrategy
true
end
- def clone_repo
- end
+ def clone_repo; end
- def update
- end
+ def update; end
- def current_revision
- end
+ def current_revision; end
def extract_ref(specs)
key = REF_TYPES.find { |type| specs.key?(type) }
@@ -331,20 +325,10 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
if cached_location.exist?
puts "Already downloaded: #{cached_location}"
else
- had_incomplete_download = temporary_path.exist?
begin
_fetch
rescue ErrorDuringExecution
- # 33 == range not supported
- # try wiping the incomplete download and retrying once
- unless $CHILD_STATUS.exitstatus == 33 && had_incomplete_download
- raise CurlDownloadStrategyError, @url
- end
-
- ohai "Trying a full download"
- temporary_path.unlink
- had_incomplete_download = false
- retry
+ raise CurlDownloadStrategyError, @url
end
ignore_interrupts { temporary_path.rename(cached_location) }
end
@@ -375,75 +359,59 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
ohai "Downloading from #{url}"
end
- urls = actual_urls(url)
- unless urls.empty?
- ohai "Downloading from #{urls.last}"
- if !ENV["HOMEBREW_NO_INSECURE_REDIRECT"].nil? && url.start_with?("https://") &&
- urls.any? { |u| !u.start_with? "https://" }
- puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
- raise CurlDownloadStrategyError, url
- end
- url = urls.last
- end
-
- curl url, "-C", downloaded_size, "-o", temporary_path
+ curl_download resolved_url(url), to: temporary_path
end
# Curl options to be always passed to curl,
- # with raw head calls (`curl -I`) or with actual `fetch`.
+ # with raw head calls (`curl --head`) or with actual `fetch`.
def _curl_opts
- copts = []
- copts << "--user" << meta.fetch(:user) if meta.key?(:user)
- copts
+ return ["--user", meta.fetch(:user)] if meta.key?(:user)
+ []
end
- def actual_urls(url)
- urls = []
- curl_args = _curl_opts << "-I" << "-L" << url
- Utils.popen_read("curl", *curl_args).scan(/^Location: (.+)$/).map do |m|
- urls << URI.join(urls.last || url, m.first.chomp).to_s
+ def resolved_url(url)
+ redirect_url, _, status = curl_output(
+ *_curl_opts, "--silent", "--head",
+ "--write-out", "%{redirect_url}",
+ "--output", "/dev/null",
+ url.to_s
+ )
+
+ return url unless status.success?
+ return url if redirect_url.empty?
+
+ ohai "Downloading from #{redirect_url}"
+ if ENV["HOMEBREW_NO_INSECURE_REDIRECT"] &&
+ url.start_with?("https://") && !redirect_url.start_with?("https://")
+ puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
+ raise CurlDownloadStrategyError, url
end
- urls
- end
- def downloaded_size
- temporary_path.size? || 0
+ redirect_url
end
- def curl(*args)
+ def curl(*args, **options)
args.concat _curl_opts
args << "--connect-timeout" << "5" unless mirrors.empty?
- super
+ super(*args, **options)
end
end
# Detect and download from Apache Mirror
class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
def apache_mirrors
- rd, wr = IO.pipe
- buf = ""
-
- pid = fork do
- ENV.delete "HOMEBREW_CURL_VERBOSE"
- rd.close
- $stdout.reopen(wr)
- $stderr.reopen(wr)
- curl "#{@url}&asjson=1"
- end
- wr.close
+ mirrors, = Open3.capture3(
+ *curl_args(*_curl_opts, "--silent", "--location", "#{@url}&asjson=1"),
+ )
- rd.readline if ARGV.verbose? # Remove Homebrew output
- buf << rd.read until rd.eof?
- rd.close
- Process.wait(pid)
- buf
+ JSON.parse(mirrors)
end
def _fetch
return super if @tried_apache_mirror
@tried_apache_mirror = true
- mirrors = JSON.parse(apache_mirrors)
+ mirrors = apache_mirrors
path_info = mirrors.fetch("path_info")
@url = mirrors.fetch("preferred") + path_info
@mirrors |= %W[https://archive.apache.org/dist/#{path_info}]
@@ -460,7 +428,7 @@ end
class CurlPostDownloadStrategy < CurlDownloadStrategy
def _fetch
base_url, data = @url.split("?")
- curl base_url, "-d", data, "-C", downloaded_size, "-o", temporary_path
+ curl_download base_url, "--data", data, to: temporary_path
end
end
@@ -530,7 +498,7 @@ class S3DownloadStrategy < CurlDownloadStrategy
s3url = obj.public_url
end
- curl s3url, "-C", downloaded_size, "-o", temporary_path
+ curl_download s3url, to: temporary_path
end
end
@@ -566,7 +534,7 @@ class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
end
def _fetch
- curl download_url, "-C", downloaded_size, "-o", temporary_path
+ curl_download download_url, to: temporary_path
end
private
@@ -615,7 +583,7 @@ class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDo
def _fetch
# HTTP request header `Accept: application/octet-stream` is required.
# Without this, the GitHub API will respond with metadata, not binary.
- curl download_url, "-C", downloaded_size, "-o", temporary_path, "-H", "Accept: application/octet-stream"
+ curl_download download_url, "--header", "Accept: application/octet-stream", to: temporary_path
end
private
@@ -915,18 +883,27 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
def github_last_commit
return if ENV["HOMEBREW_NO_GITHUB_API"]
- output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \
- "-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
+ output, _, status = curl_output(
+ "--silent", "--head", "--location",
+ "-H", "Accept: application/vnd.github.v3.sha",
+ "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
+ )
+
+ return unless status.success?
- commit = output[/^ETag: \"(\h+)\"/, 1] if status.success?
+ commit = output[/^ETag: \"(\h+)\"/, 1]
version.update_commit(commit) if commit
commit
end
def multiple_short_commits_exist?(commit)
return if ENV["HOMEBREW_NO_GITHUB_API"]
- output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \
- "-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
+
+ output, _, status = curl_output(
+ "--silent", "--head", "--location",
+ "-H", "Accept: application/vnd.github.v3.sha",
+ "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
+ )
!(status.success? && output && output[/^Status: (200)/, 1] == "200")
end
@@ -1159,15 +1136,13 @@ class DownloadStrategyDetector
SubversionDownloadStrategy
when %r{^cvs://}
CVSDownloadStrategy
- when %r{^https?://(.+?\.)?googlecode\.com/hg}
- MercurialDownloadStrategy
- when %r{^hg://}
+ when %r{^hg://}, %r{^https?://(.+?\.)?googlecode\.com/hg}
MercurialDownloadStrategy
when %r{^bzr://}
BazaarDownloadStrategy
when %r{^fossil://}
FossilDownloadStrategy
- when %r{^http://svn\.apache\.org/repos/}, %r{^svn\+http://}
+ when %r{^svn\+http://}, %r{^http://svn\.apache\.org/repos/}
SubversionDownloadStrategy
when %r{^https?://(.+?\.)?sourceforge\.net/hgweb/}
MercurialDownloadStrategy
diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb
index 8b4cddc59..22a7fe023 100644
--- a/Library/Homebrew/exceptions.rb
+++ b/Library/Homebrew/exceptions.rb
@@ -416,7 +416,7 @@ class BuildError < RuntimeError
puts
- if issues && !issues.empty?
+ unless issues&.empty?
puts "These open issues may also help:"
puts issues.map { |i| "#{i["title"]} #{i["html_url"]}" }.join("\n")
end
@@ -555,12 +555,12 @@ end
# raised when a single patch file is not found and apply hasn't been specified
class MissingApplyError < RuntimeError; end
-class BottleVersionMismatchError < RuntimeError
- def initialize(bottle_file, bottle_version, formula, formula_version)
+class BottleFormulaUnavailableError < RuntimeError
+ def initialize(bottle_path, formula_path)
super <<-EOS.undent
- Bottle version mismatch
- Bottle: #{bottle_file} (#{bottle_version})
- Formula: #{formula.full_name} (#{formula_version})
+ This bottle does not contain the formula file:
+ #{bottle_path}
+ #{formula_path}
EOS
end
end
diff --git a/Library/Homebrew/extend/ARGV.rb b/Library/Homebrew/extend/ARGV.rb
index c6cb54f5d..63a0f3e40 100644
--- a/Library/Homebrew/extend/ARGV.rb
+++ b/Library/Homebrew/extend/ARGV.rb
@@ -144,10 +144,10 @@ module HomebrewArgvExtension
def value(name)
arg_prefix = "--#{name}="
flag_with_value = find { |arg| arg.start_with?(arg_prefix) }
- flag_with_value.strip_prefix(arg_prefix) if flag_with_value
+ flag_with_value&.strip_prefix(arg_prefix)
end
- # Returns an array of values that were given as a comma-seperated list.
+ # Returns an array of values that were given as a comma-separated list.
# @see value
def values(name)
return unless val = value(name)
@@ -236,7 +236,7 @@ module HomebrewArgvExtension
def bottle_arch
arch = value "bottle-arch"
- arch.to_sym if arch
+ arch&.to_sym
end
def build_from_source?
diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb
index 283e90b69..ea1b99501 100644
--- a/Library/Homebrew/extend/ENV.rb
+++ b/Library/Homebrew/extend/ENV.rb
@@ -28,7 +28,7 @@ module EnvActivation
end
def clear_sensitive_environment!
- ENV.keys.each do |key|
+ ENV.each_key do |key|
next unless /(cookie|key|token)/i =~ key
ENV.delete key
end
diff --git a/Library/Homebrew/extend/ENV/shared.rb b/Library/Homebrew/extend/ENV/shared.rb
index b51ade48b..15488ee19 100644
--- a/Library/Homebrew/extend/ENV/shared.rb
+++ b/Library/Homebrew/extend/ENV/shared.rb
@@ -260,10 +260,6 @@ module SharedEnvExtension
set_cpu_flags(flags)
end
- def java_cache
- append "_JAVA_OPTIONS", "-Duser.home=#{HOMEBREW_CACHE}/java_cache"
- end
-
# ld64 is a newer linker provided for Xcode 2.5
# @private
def ld64
diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb
index a2e800803..4e5d0683a 100644
--- a/Library/Homebrew/extend/ENV/std.rb
+++ b/Library/Homebrew/extend/ENV/std.rb
@@ -233,8 +233,8 @@ module Stdenv
def make_jobs
# '-j' requires a positive integral argument
- if self["HOMEBREW_MAKE_JOBS"].to_i > 0
- self["HOMEBREW_MAKE_JOBS"].to_i
+ if (jobs = self["HOMEBREW_MAKE_JOBS"].to_i).positive?
+ jobs
else
Hardware::CPU.cores
end
diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb
index 692fd3623..b4f0dfcac 100644
--- a/Library/Homebrew/extend/ENV/super.rb
+++ b/Library/Homebrew/extend/ENV/super.rb
@@ -24,8 +24,7 @@ module Superenv
end
# @private
- def self.bin
- end
+ def self.bin; end
def reset
super
@@ -138,7 +137,6 @@ module Superenv
def determine_pkg_config_libdir
PATH.new(
- "/usr/lib/pkgconfig",
homebrew_extra_pkg_config_paths,
).existing
end
@@ -325,11 +323,9 @@ module Superenv
end
end
- def set_x11_env_if_installed
- end
+ def set_x11_env_if_installed; end
- def set_cpu_flags(*)
- end
+ def set_cpu_flags(_, _ = "", _ = {}); end
end
require "extend/os/extend/ENV/super"
diff --git a/Library/Homebrew/extend/cachable.rb b/Library/Homebrew/extend/cachable.rb
new file mode 100644
index 000000000..69d86ccb7
--- /dev/null
+++ b/Library/Homebrew/extend/cachable.rb
@@ -0,0 +1,9 @@
+module Cachable
+ def cache
+ @cache ||= {}
+ end
+
+ def clear_cache
+ cache.clear
+ end
+end
diff --git a/Library/Homebrew/extend/fileutils.rb b/Library/Homebrew/extend/fileutils.rb
index 52d4cbf51..ed5bfe6c3 100644
--- a/Library/Homebrew/extend/fileutils.rb
+++ b/Library/Homebrew/extend/fileutils.rb
@@ -3,7 +3,7 @@ require "tmpdir"
require "etc"
# Homebrew extends Ruby's `FileUtils` to make our code more readable.
-# @see http://ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html Ruby's FileUtils API
+# @see https://ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html Ruby's FileUtils API
module FileUtils
# Create a temporary directory then yield. When the block returns,
# recursively delete the temporary directory. Passing opts[:retain]
diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb
index caa85ffca..1931b398d 100644
--- a/Library/Homebrew/extend/os/mac/development_tools.rb
+++ b/Library/Homebrew/extend/os/mac/development_tools.rb
@@ -9,7 +9,7 @@ class DevelopmentTools
@locate[key] = if (located_tool = original_locate(tool))
located_tool
elsif MacOS.version > :tiger
- path = Utils.popen_read("/usr/bin/xcrun", "-no-cache", "-find", tool).chomp
+ path = Utils.popen_read("/usr/bin/xcrun", "-no-cache", "-find", tool, err: :close).chomp
Pathname.new(path) if File.executable?(path)
end
end
@@ -43,11 +43,16 @@ class DevelopmentTools
end
def custom_installation_instructions
- if MacOS.version > :tiger
+ if MacOS.version > :leopard
<<-EOS.undent
Install GNU's GCC
brew install gcc
EOS
+ elsif MacOS.version > :tiger
+ <<-EOS.undent
+ Install GNU's GCC
+ brew install gcc@4.6
+ EOS
else
# Tiger doesn't ship with apple-gcc42, and this is required to build
# some software that doesn't build properly with FSF GCC.
@@ -55,7 +60,7 @@ class DevelopmentTools
Install Apple's GCC
brew install apple-gcc42
or GNU's GCC
- brew install gcc
+ brew install gcc@4.6
EOS
end
end
@@ -77,10 +82,10 @@ class DevelopmentTools
end
end
- def curl_handles_most_https_homepages?
- # The system Curl is too old for some modern HTTPS homepages on
+ def curl_handles_most_https_certificates?
+ # The system Curl is too old for some modern HTTPS certificates on
# older macOS versions.
- MacOS.version >= :el_capitan
+ ENV["HOMEBREW_SYSTEM_CURL_TOO_OLD"].nil?
end
def subversion_handles_most_https_certificates?
diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb
index 0cdd7b115..9f7b18b49 100644
--- a/Library/Homebrew/extend/os/mac/diagnostic.rb
+++ b/Library/Homebrew/extend/os/mac/diagnostic.rb
@@ -195,8 +195,9 @@ module Homebrew
end
def check_ruby_version
- ruby_version = "2.0"
- return if RUBY_VERSION[/\d\.\d/] == ruby_version
+ ruby_version = "2.3.3"
+ return if RUBY_VERSION == ruby_version
+ return if ARGV.homebrew_developer? && OS::Mac.prerelease?
<<-EOS.undent
Ruby version #{RUBY_VERSION} is unsupported on #{MacOS.version}. Homebrew
diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb
index f97a2dbbb..5872c2264 100644
--- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb
+++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb
@@ -28,7 +28,7 @@ module Superenv
# @private
def homebrew_extra_pkg_config_paths
paths = \
- ["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
+ ["/usr/lib/pkgconfig", "#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
paths << "#{MacOS::X11.lib}/pkgconfig" << "#{MacOS::X11.share}/pkgconfig" if x11?
paths
end
@@ -96,9 +96,13 @@ module Superenv
self["SDKROOT"] = MacOS.sdk_path
end
- # Filter out symbols known not to be defined on 10.11 since GNU Autotools
- # can't reliably figure this out with Xcode 8 on its own yet.
- if MacOS.version == "10.11" && MacOS::Xcode.installed? && MacOS::Xcode.version >= "8.0"
+ # Filter out symbols known not to be defined since GNU Autotools can't
+ # reliably figure this out with Xcode 8 and above.
+ if MacOS.version == "10.12" && MacOS::Xcode.installed? && MacOS::Xcode.version >= "9.0"
+ %w[fmemopen futimens open_memstream utimensat].each do |s|
+ ENV["ac_cv_func_#{s}"] = "no"
+ end
+ elsif MacOS.version == "10.11" && MacOS::Xcode.installed? && MacOS::Xcode.version >= "8.0"
%w[basename_r clock_getres clock_gettime clock_settime dirname_r
getentropy mkostemp mkostemps timingsafe_bcmp].each do |s|
ENV["ac_cv_func_#{s}"] = "no"
diff --git a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb
index 66e038774..32e5774f6 100644
--- a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb
+++ b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb
@@ -67,11 +67,19 @@ module FormulaCellarChecks
checker = LinkageChecker.new(keg, formula)
return unless checker.broken_dylibs?
- problem_if_output <<-EOS.undent
- The installation was broken.
- Broken dylib links found:
- #{checker.broken_dylibs.to_a * "\n "}
+ output = <<-EOS.undent
+ #{formula} has broken dynamic library links:
+ #{checker.broken_dylibs.to_a * "\n "}
EOS
+ tab = Tab.for_keg(keg)
+ if tab.poured_from_bottle
+ output += <<-EOS.undent
+ Rebuild this from source with:
+ brew reinstall --build-from-source #{formula}
+ If that's successful, file an issue#{formula.tap ? " here:\n #{formula.tap.issues_url}" : "."}
+ EOS
+ end
+ problem_if_output output
end
def audit_installed
diff --git a/Library/Homebrew/extend/os/mac/hardware/cpu.rb b/Library/Homebrew/extend/os/mac/hardware/cpu.rb
index 22d118e1a..b97c280cd 100644
--- a/Library/Homebrew/extend/os/mac/hardware/cpu.rb
+++ b/Library/Homebrew/extend/os/mac/hardware/cpu.rb
@@ -50,6 +50,8 @@ module Hardware
:broadwell
when 0x37fc219f # Skylake
:skylake
+ when 0x0f817246 # Kaby Lake
+ :kabylake
else
:dunno
end
diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb
index 767d83ff9..e3d6880ba 100644
--- a/Library/Homebrew/extend/pathname.rb
+++ b/Library/Homebrew/extend/pathname.rb
@@ -59,7 +59,7 @@ module DiskUsageExtension
end
# Homebrew extends Ruby's `Pathname` to make our code more readable.
-# @see http://ruby-doc.org/stdlib-1.8.7/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API
+# @see https://ruby-doc.org/stdlib-1.8.7/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API
class Pathname
include DiskUsageExtension
@@ -186,7 +186,7 @@ class Pathname
begin
tf.chown(uid, gid)
tf.chmod(old_stat.mode)
- rescue Errno::EPERM
+ rescue Errno::EPERM # rubocop:disable Lint/HandleExceptions
end
File.rename(tf.path, self)
diff --git a/Library/Homebrew/extend/string.rb b/Library/Homebrew/extend/string.rb
index ae7a209db..b96f12994 100644
--- a/Library/Homebrew/extend/string.rb
+++ b/Library/Homebrew/extend/string.rb
@@ -60,7 +60,7 @@ module StringInreplaceExtension
result
end
- # Looks for Makefile style variable defintions and replaces the
+ # Looks for Makefile style variable definitions and replaces the
# value with "new_value", or removes the definition entirely.
def change_make_var!(flag, new_value)
return if gsub!(/^#{Regexp.escape(flag)}[ \t]*=[ \t]*(.*)$/, "#{flag}=#{new_value}", false)
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index 8cea85a99..61042aae7 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -472,7 +472,7 @@ class Formula
return true if devel && tab.devel_version && tab.devel_version < devel.version
if options[:fetch_head]
- return false unless head && head.downloader.is_a?(VCSDownloadStrategy)
+ return false unless head&.downloader.is_a?(VCSDownloadStrategy)
downloader = head.downloader
downloader.shutup! unless ARGV.verbose?
downloader.commit_outdated?(version.version.commit)
@@ -1041,14 +1041,14 @@ class Formula
# keg's formula is deleted.
begin
keg = Keg.for(path)
- rescue NotAKegError, Errno::ENOENT
+ rescue NotAKegError, Errno::ENOENT # rubocop:disable Lint/HandleExceptions
# file doesn't belong to any keg.
else
tab_tap = Tab.for_keg(keg).tap
return false if tab_tap.nil? # this keg doesn't below to any core/tap formula, most likely coming from a DIY install.
begin
Formulary.factory(keg.name)
- rescue FormulaUnavailableError
+ rescue FormulaUnavailableError # rubocop:disable Lint/HandleExceptions
# formula for this keg is deleted, so defer to whitelist
rescue TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
return false # this keg belongs to another formula
@@ -1115,8 +1115,8 @@ class Formula
# @private
def unlock
- @lock.unlock unless @lock.nil?
- @oldname_lock.unlock unless @oldname_lock.nil?
+ @lock&.unlock
+ @oldname_lock&.unlock
end
def migration_needed?
@@ -1182,7 +1182,8 @@ class Formula
# Returns false if the formula wasn't installed with an alias.
def installed_alias_target_changed?
target = current_installed_alias_target
- target && target.name != name
+ return false unless target
+ target.name != name
end
# Is this formula the target of an alias used to install an old formula?
@@ -1378,12 +1379,13 @@ class Formula
# An array of all installed {Formula}
# @private
def self.installed
- @installed ||= racks.map do |rack|
+ @installed ||= racks.flat_map do |rack|
begin
Formulary.from_rack(rack)
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
+ []
end
- end.compact.uniq(&:name)
+ end.uniq(&:name)
end
def self.installed_with_alias_path(alias_path)
@@ -1440,13 +1442,14 @@ class Formula
# True if this formula is provided by Homebrew itself
# @private
def core_formula?
- tap && tap.core_tap?
+ tap&.core_tap?
end
# True if this formula is provided by external Tap
# @private
def tap?
- tap && !tap.core_tap?
+ return false unless tap
+ !tap.core_tap?
end
# @private
@@ -1525,10 +1528,10 @@ class Formula
"oldname" => oldname,
"aliases" => aliases,
"versions" => {
- "stable" => (stable.version.to_s if stable),
+ "stable" => stable&.version.to_s,
"bottle" => bottle ? true : false,
- "devel" => (devel.version.to_s if devel),
- "head" => (head.version.to_s if head),
+ "devel" => devel&.version.to_s,
+ "head" => head&.version.to_s,
},
"revision" => revision,
"version_scheme" => version_scheme,
@@ -1570,7 +1573,7 @@ class Formula
"root_url" => bottle_spec.root_url,
}
bottle_info["files"] = {}
- bottle_spec.collector.keys.each do |os|
+ bottle_spec.collector.keys.each do |os| # rubocop:disable Performance/HashEachMethods
checksum = bottle_spec.collector[os]
bottle_info["files"][os] = {
"url" => "#{bottle_spec.root_url}/#{Bottle::Filename.create(self, os, bottle_spec.rebuild)}",
@@ -1613,6 +1616,7 @@ class Formula
def run_test
@prefix_returns_versioned_prefix = true
old_home = ENV["HOME"]
+ old_java_opts = ENV["_JAVA_OPTIONS"]
old_curl_home = ENV["CURL_HOME"]
old_tmpdir = ENV["TMPDIR"]
old_temp = ENV["TEMP"]
@@ -1626,6 +1630,7 @@ class Formula
ENV["TERM"] = "dumb"
ENV["PATH"] = PATH.new(old_path).append(HOMEBREW_PREFIX/"bin")
ENV["HOMEBREW_PATH"] = nil
+ ENV["_JAVA_OPTIONS"] = "#{old_java_opts} -Duser.home=#{HOMEBREW_CACHE}/java_cache"
ENV.clear_sensitive_environment!
@@ -1638,7 +1643,7 @@ class Formula
with_logging("test") do
test
end
- rescue Exception
+ rescue Exception # rubocop:disable Lint/RescueException
staging.retain! if ARGV.debug?
raise
end
@@ -1646,6 +1651,7 @@ class Formula
ensure
@testpath = nil
ENV["HOME"] = old_home
+ ENV["_JAVA_OPTIONS"] = old_java_opts
ENV["CURL_HOME"] = old_curl_home
ENV["TMPDIR"] = old_tmpdir
ENV["TEMP"] = old_temp
@@ -1662,8 +1668,7 @@ class Formula
end
# @private
- def test
- end
+ def test; end
# @private
def test_fixtures(file)
@@ -1678,8 +1683,7 @@ class Formula
# system "./configure", "--prefix=#{prefix}"
# system "make", "install"
# end</pre>
- def install
- end
+ def install; end
protected
@@ -1888,11 +1892,13 @@ class Formula
mkdir_p env_home
old_home = ENV["HOME"]
+ old_java_opts = ENV["_JAVA_OPTIONS"]
old_curl_home = ENV["CURL_HOME"]
old_path = ENV["HOMEBREW_PATH"]
unless ARGV.interactive?
ENV["HOME"] = env_home
+ ENV["_JAVA_OPTIONS"] = "#{old_java_opts} -Duser.home=#{HOMEBREW_CACHE}/java_cache"
ENV["CURL_HOME"] = old_curl_home || old_home
end
ENV["HOMEBREW_PATH"] = nil
@@ -1907,6 +1913,7 @@ class Formula
@buildpath = nil
unless ARGV.interactive?
ENV["HOME"] = old_home
+ ENV["_JAVA_OPTIONS"] = old_java_opts
ENV["CURL_HOME"] = old_curl_home
end
ENV["HOMEBREW_PATH"] = old_path
@@ -1924,28 +1931,28 @@ class Formula
end
end
- def self.method_added(method)
- case method
- when :brew
- raise "You cannot override Formula#brew in class #{name}"
- when :test
- define_method(:test_defined?) { true }
- when :options
- instance = allocate
+ # The methods below define the formula DSL.
+ class << self
+ include BuildEnvironment::DSL
- specs.each do |spec|
- instance.options.each do |opt, desc|
- spec.option(opt[/^--(.+)$/, 1], desc)
+ def method_added(method)
+ case method
+ when :brew
+ raise "You cannot override Formula#brew in class #{name}"
+ when :test
+ define_method(:test_defined?) { true }
+ when :options
+ instance = allocate
+
+ specs.each do |spec|
+ instance.options.each do |opt, desc|
+ spec.option(opt[/^--(.+)$/, 1], desc)
+ end
end
- end
- remove_method(:options)
+ remove_method(:options)
+ end
end
- end
-
- # The methods below define the formula DSL.
- class << self
- include BuildEnvironment::DSL
# The reason for why this software is not linked (by default) to
# {::HOMEBREW_PREFIX}.
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index b2a528381..7cd87e751 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -58,13 +58,14 @@ class FormulaInstaller
@options = Options.new
@invalid_option_names = []
@requirement_messages = []
-
- @@attempted ||= Set.new
-
@poured_bottle = false
@pour_failed = false
end
+ def self.attempted
+ @attempted ||= Set.new
+ end
+
# When no build tools are available and build flags are passed through ARGV,
# it's necessary to interrupt the user before any sort of installation
# can proceed. Only invoked when the user has no developer tools.
@@ -84,14 +85,12 @@ class FormulaInstaller
return false if @pour_failed
- bottle = formula.bottle
- return false unless bottle
+ return false if !formula.bottled? && !formula.local_bottle_path
return true if force_bottle?
return false if build_from_source? || build_bottle? || interactive?
return false if ARGV.cc
return false unless options.empty?
return false if formula.bottle_disabled?
- return true if formula.local_bottle_path
unless formula.pour_bottle?
if install_bottle_options[:warn] && formula.pour_bottle_check_unsatisfied_reason
opoo <<-EOS.undent
@@ -102,6 +101,7 @@ class FormulaInstaller
return false
end
+ bottle = formula.bottle_specification
unless bottle.compatible_cellar?
if install_bottle_options[:warn]
opoo <<-EOS.undent
@@ -146,7 +146,7 @@ class FormulaInstaller
end
def check_install_sanity
- raise FormulaInstallationAlreadyAttemptedError, formula if @@attempted.include?(formula)
+ raise FormulaInstallationAlreadyAttemptedError, formula if self.class.attempted.include?(formula)
return if ignore_deps?
@@ -237,6 +237,15 @@ class FormulaInstaller
raise CannotInstallFormulaError, message
end
+ # Warn if a more recent version of this formula is available in the tap.
+ begin
+ if formula.pkg_version < (v = Formulary.factory(formula.full_name).pkg_version)
+ opoo "#{formula.full_name} #{v} is available and more recent than version #{formula.pkg_version}."
+ end
+ rescue FormulaUnavailableError
+ nil
+ end
+
check_conflicts
if !pour_bottle? && !formula.bottle_unneeded? && !DevelopmentTools.installed?
@@ -270,7 +279,7 @@ class FormulaInstaller
oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip
end
- if formula.tap && !formula.tap.private?
+ unless formula.tap&.private?
action = "#{formula.full_name} #{options}".strip
Utils::Analytics.report_event("install", action)
@@ -279,12 +288,12 @@ class FormulaInstaller
end
end
- @@attempted << formula
+ self.class.attempted << formula
if pour_bottle?(warn: true)
begin
pour
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
# any exceptions must leave us with nothing installed
ignore_interrupts do
formula.prefix.rmtree if formula.prefix.directory?
@@ -310,7 +319,12 @@ class FormulaInstaller
clean
# Store the formula used to build the keg in the keg.
- s = formula.path.read.gsub(/ bottle do.+?end\n\n?/m, "")
+ formula_contents = if formula.local_bottle_path
+ Utils::Bottles.formula_contents formula.local_bottle_path, name: formula.name
+ else
+ formula.path.read
+ end
+ s = formula_contents.gsub(/ bottle do.+?end\n\n?/m, "")
brew_prefix = formula.prefix/".brew"
brew_prefix.mkdir
Pathname(brew_prefix/"#{formula.name}.rb").atomic_write(s)
@@ -554,14 +568,14 @@ class FormulaInstaller
oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}"
fi.install
fi.finish
- rescue Exception
+ rescue Exception # rubocop:disable Lint/RescueException
ignore_interrupts do
tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory?
linked_keg.link if keg_was_linked
end
raise
else
- ignore_interrupts { tmp_keg.rmtree if tmp_keg && tmp_keg.directory? }
+ ignore_interrupts { tmp_keg.rmtree if tmp_keg&.directory? }
end
def caveats
@@ -604,6 +618,12 @@ class FormulaInstaller
# let's reset Utils.git_available? if we just installed git
Utils.clear_git_available_cache if formula.name == "git"
+
+ # use installed curl when it's needed and available
+ if formula.name == "curl" &&
+ !DevelopmentTools.curl_handles_most_https_certificates?
+ ENV["HOMEBREW_CURL"] = formula.opt_bin/"curl"
+ end
ensure
unlock
end
@@ -679,8 +699,6 @@ class FormulaInstaller
#{formula.specified_path}
].concat(build_argv)
- Sandbox.print_sandbox_message if Sandbox.formula?(formula)
-
Utils.safe_fork do
# Invalidate the current sudo timestamp in case a build script calls sudo.
# Travis CI's Linux sudoless workers have a weird sudo that fails here.
@@ -706,7 +724,7 @@ class FormulaInstaller
if !formula.prefix.directory? || Keg.new(formula.prefix).empty_installation?
raise "Empty installation"
end
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
e.options = display_options(formula) if e.is_a?(BuildError)
ignore_interrupts do
# any exceptions must leave us with nothing installed
@@ -767,7 +785,7 @@ class FormulaInstaller
puts " brew link #{formula.name}"
@show_summary_heading = true
Homebrew.failed = true
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "An unexpected error occurred during the `brew link` step"
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
puts e
@@ -798,7 +816,7 @@ class FormulaInstaller
formula.plist_path.chmod 0644
log = formula.var/"log"
log.mkpath if formula.plist.include? log.to_s
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "Failed to install plist file"
ohai e, e.backtrace if debug?
Homebrew.failed = true
@@ -806,7 +824,7 @@ class FormulaInstaller
def fix_dynamic_linkage(keg)
keg.fix_dynamic_linkage
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "Failed to fix install linkage"
puts "The formula built, but you may encounter issues using it or linking other"
puts "formula against it."
@@ -818,7 +836,7 @@ class FormulaInstaller
def clean
ohai "Cleaning" if verbose?
Cleaner.new(formula).clean
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
opoo "The cleaning step did not complete successfully"
puts "Still, the installation was successful, so we will link it into your prefix"
ohai e, e.backtrace if debug?
@@ -828,7 +846,7 @@ class FormulaInstaller
def post_install
Homebrew.run_post_install(formula)
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
opoo "The post-install step did not complete successfully"
puts "You can try again using `brew postinstall #{formula.full_name}`"
ohai e, e.backtrace if debug?
@@ -888,27 +906,31 @@ class FormulaInstaller
super
end
+ def self.locked
+ @locked ||= []
+ end
+
private
attr_predicate :hold_locks?
def lock
- return unless (@@locked ||= []).empty?
+ return unless self.class.locked.empty?
unless ignore_deps?
formula.recursive_dependencies.each do |dep|
- @@locked << dep.to_formula
+ self.class.locked << dep.to_formula
end
end
- @@locked.unshift(formula)
- @@locked.uniq!
- @@locked.each(&:lock)
+ self.class.locked.unshift(formula)
+ self.class.locked.uniq!
+ self.class.locked.each(&:lock)
@hold_locks = true
end
def unlock
return unless hold_locks?
- @@locked.each(&:unlock)
- @@locked.clear
+ self.class.locked.each(&:unlock)
+ self.class.locked.clear
@hold_locks = false
end
diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb
index bb6803567..c10c69e67 100644
--- a/Library/Homebrew/formula_versions.rb
+++ b/Library/Homebrew/formula_versions.rb
@@ -44,7 +44,7 @@ class FormulaVersions
# continue walking the history
ohai "#{e} in #{name} at revision #{rev}", e.backtrace if ARGV.debug?
rescue FormulaUnavailableError
- # Suppress this error
+ return
ensure
Homebrew.raise_deprecation_exceptions = false
end
diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb
index 195d15cec..fddeac631 100644
--- a/Library/Homebrew/formulary.rb
+++ b/Library/Homebrew/formulary.rb
@@ -1,18 +1,19 @@
require "digest/md5"
require "tap"
+require "extend/cachable"
# The Formulary is responsible for creating instances of Formula.
# It is not meant to be used directly from formulae.
module Formulary
- FORMULAE = {}
+ extend Cachable
def self.formula_class_defined?(path)
- FORMULAE.key?(path)
+ cache.key?(path)
end
def self.formula_class_get(path)
- FORMULAE.fetch(path)
+ cache.fetch(path)
end
def self.load_formula(name, path, contents, namespace)
@@ -44,7 +45,7 @@ module Formulary
contents = path.open("r") { |f| ensure_utf8_encoding(f).read }
namespace = "FormulaNamespace#{Digest::MD5.hexdigest(path.to_s)}"
klass = load_formula(name, path, contents, namespace)
- FORMULAE[path] = klass
+ cache[path] = klass
end
if IO.method_defined?(:set_encoding)
@@ -122,14 +123,18 @@ module Formulary
super name, Formulary.path(full_name)
end
- def get_formula(spec, alias_path: nil)
- formula = super
- formula.local_bottle_path = @bottle_filename
- formula_version = formula.pkg_version
- bottle_version = Utils::Bottles.resolve_version(@bottle_filename)
- unless formula_version == bottle_version
- raise BottleVersionMismatchError.new(@bottle_filename, bottle_version, formula, formula_version)
+ def get_formula(spec, **)
+ contents = Utils::Bottles.formula_contents @bottle_filename, name: name
+ formula = begin
+ Formulary.from_contents name, @bottle_filename, contents, spec
+ rescue FormulaUnreadableError => e
+ opoo <<-EOS.undent
+ Unreadable formula in #{@bottle_filename}:
+ #{e}
+ EOS
+ super
end
+ formula.local_bottle_path = @bottle_filename
formula
end
end
@@ -165,7 +170,7 @@ module Formulary
def load_file
HOMEBREW_CACHE_FORMULA.mkpath
FileUtils.rm_f(path)
- curl url, "-o", path
+ curl_download url, to: path
super
rescue MethodDeprecatedError => e
if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/}
diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb
index 9f79781b4..32b5377a0 100644
--- a/Library/Homebrew/global.rb
+++ b/Library/Homebrew/global.rb
@@ -45,11 +45,15 @@ module Homebrew
@failed == true
end
- attr_writer :raise_deprecation_exceptions
+ attr_writer :raise_deprecation_exceptions, :auditing
def raise_deprecation_exceptions?
@raise_deprecation_exceptions == true
end
+
+ def auditing?
+ @auditing == true
+ end
end
end
diff --git a/Library/Homebrew/gpg.rb b/Library/Homebrew/gpg.rb
index cb9e367df..de2089dda 100644
--- a/Library/Homebrew/gpg.rb
+++ b/Library/Homebrew/gpg.rb
@@ -7,8 +7,7 @@ class Gpg
next unless gpg_short_version
gpg_version = Version.create(gpg_short_version.to_s)
@version = gpg_version
- gpg_version == Version.create("2.0") ||
- gpg_version == Version.create("2.1")
+ gpg_version >= Version.create("2.0")
end
end
@@ -20,7 +19,7 @@ class Gpg
find_gpg("gpg2")
end
- GPG_EXECUTABLE = gpg2 || gpg
+ GPG_EXECUTABLE = gpg || gpg2
def self.available?
File.executable?(GPG_EXECUTABLE.to_s)
@@ -41,8 +40,27 @@ class Gpg
Name-Real: Testing
Name-Email: testing@foo.bar
Expire-Date: 1d
+ %no-protection
%commit
EOS
system GPG_EXECUTABLE, "--batch", "--gen-key", "batch.gpg"
end
+
+ def self.cleanup_test_processes!
+ odie "No GPG present to test against!" unless available?
+ gpgconf = Pathname.new(GPG_EXECUTABLE).parent/"gpgconf"
+
+ system gpgconf, "--kill", "gpg-agent"
+ system gpgconf, "--homedir", "keyrings/live", "--kill",
+ "gpg-agent"
+ end
+
+ def self.test(path)
+ create_test_key(path)
+ begin
+ yield
+ ensure
+ cleanup_test_processes!
+ end
+ end
end
diff --git a/Library/Homebrew/install_renamed.rb b/Library/Homebrew/install_renamed.rb
index 5e200244f..dc5d4cda8 100644
--- a/Library/Homebrew/install_renamed.rb
+++ b/Library/Homebrew/install_renamed.rb
@@ -16,12 +16,12 @@ module InstallRenamed
end
end
- def +(path)
- super(path).extend(InstallRenamed)
+ def +(other)
+ super(other).extend(InstallRenamed)
end
- def /(path)
- super(path).extend(InstallRenamed)
+ def /(other)
+ super(other).extend(InstallRenamed)
end
private
diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb
index 8fcbecfbd..677a97c85 100644
--- a/Library/Homebrew/keg.rb
+++ b/Library/Homebrew/keg.rb
@@ -253,6 +253,11 @@ class Keg
FileUtils.rm_rf bad_tap_opt if bad_tap_opt.directory?
end
+ aliases.each do |a|
+ alias_symlink = opt/a
+ alias_symlink.delete if alias_symlink.symlink? || alias_symlink.exist?
+ end
+
Pathname.glob("#{opt_record}@*").each do |a|
a = a.basename
next if aliases.include?(a)
@@ -333,7 +338,7 @@ class Keg
dir if dir.directory? && dir.children.any? { |f| f.basename.to_s.start_with?("_") }
when :fish then path/"share/fish/vendor_completions.d"
end
- dir && dir.directory? && !dir.children.empty?
+ dir&.directory? && !dir.children.empty?
end
def functions_installed?(shell)
diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb
index ad4c01021..71773db81 100644
--- a/Library/Homebrew/keg_relocate.rb
+++ b/Library/Homebrew/keg_relocate.rb
@@ -124,6 +124,7 @@ class Keg
next true if pn.symlink?
next true if pn.directory?
next false if pn.basename.to_s == "orig-prefix.txt" # for python virtualenvs
+ next true if pn == self/".brew/#{name}.rb"
next true if Metafiles::EXTENSIONS.include?(pn.extname)
if pn.text_executable?
text_files << pn
@@ -156,7 +157,7 @@ class Keg
libtool_files = []
path.find do |pn|
- next if pn.symlink? || pn.directory? || pn.extname != ".la"
+ next if pn.symlink? || pn.directory? || ![".la", ".lai"].include?(pn.extname)
libtool_files << pn
end
libtool_files
diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb
index 0f8e3a4e6..bfec556d0 100644
--- a/Library/Homebrew/language/python.rb
+++ b/Library/Homebrew/language/python.rb
@@ -23,7 +23,7 @@ module Language
else
homebrew_site_packages(version)
end
- block.call python, version if block
+ block&.call python, version
end
ENV["PYTHONPATH"] = original_pythonpath
end
diff --git a/Library/Homebrew/locale.rb b/Library/Homebrew/locale.rb
index 5e778f3b4..c430d11b6 100644
--- a/Library/Homebrew/locale.rb
+++ b/Library/Homebrew/locale.rb
@@ -2,9 +2,9 @@ class Locale
class ParserError < StandardError
end
- LANGUAGE_REGEX = /(?:[a-z]{2,3})/ # ISO 639-1 or ISO 639-2
- REGION_REGEX = /(?:[A-Z]{2})/ # ISO 3166-1
- SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/ # ISO 15924
+ LANGUAGE_REGEX = /(?:[a-z]{2,3})/ # ISO 639-1 or ISO 639-2
+ REGION_REGEX = /(?:[A-Z]{2}|\d{3})/ # ISO 3166-1 or UN M.49
+ SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/ # ISO 15924
LOCALE_REGEX = /\A((?:#{LANGUAGE_REGEX}|#{REGION_REGEX}|#{SCRIPT_REGEX})(?:\-|$)){1,3}\Z/
@@ -44,8 +44,6 @@ class Locale
raise ParserError, "'#{value}' does not match #{regex}" unless value =~ regex
instance_variable_set(:"@#{key}", value)
end
-
- self
end
def include?(other)
diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md
index bfb9cd7a5..1c7c198b0 100644
--- a/Library/Homebrew/manpages/brew-cask.1.md
+++ b/Library/Homebrew/manpages/brew-cask.1.md
@@ -1,5 +1,5 @@
brew-cask(1) - a friendly binary installer for macOS
-========================================================
+====================================================
## SYNOPSIS
@@ -19,7 +19,7 @@ names, and other aspects of this manual are still subject to change.
## FREQUENTLY USED COMMANDS
- * `install` [--force] [--skip-cask-deps] [--require-sha] <token> [ <token> ... ]:
+ * `install` [--force] [--skip-cask-deps] [--require-sha] [--language=<iso-language>[,<iso-language> ... ]] <token> [ <token> ... ]:
Install Cask identified by <token>.
* `uninstall` [--force] <token> [ <token> ... ]:
@@ -34,7 +34,7 @@ names, and other aspects of this manual are still subject to change.
## COMMANDS
- * `audit` [ <token> ... ]:
+ * `audit` [--language=<iso-language>[,<iso-language> ... ]] [ <token> ... ]:
Check the given Casks for installability.
If no tokens are given on the command line, all Casks are audited.
@@ -85,7 +85,7 @@ 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.
-
+
* `outdated` [--greedy] [--verbose|--quiet] [ <token> ...]:
Without token arguments, display all the installed Casks that have newer
versions available in the tap; otherwise check only the tokens given
@@ -101,9 +101,10 @@ names, and other aspects of this manual are still subject to change.
Reinstall the given Cask.
* `search` or `-S` [<text> | /<regexp>/]:
- 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
+ Without an argument, display all locally available Casks for install; no
+ online search is performed.
+ 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> ... ]:
@@ -166,6 +167,9 @@ in a future version.
* `--appdir=<path>`:
Target location for Applications. The default value is `/Applications`.
+ * `--language=<iso-language>[,<iso-language> ... ]]`:
+ Set language of the Cask to install. The first matching language is used, otherwise the default language on the Cask. The default value is the `language of your system`.
+
* `--colorpickerdir=<path>`:
Target location for Color Pickers. The default value is `~/Library/ColorPickers`.
@@ -255,7 +259,7 @@ Environment variables specific to Homebrew-Cask:
export HOMEBREW_CASK_OPTS='--appdir=~/Applications --fontdir=/Library/Fonts'
Other environment variables:
-
+
* `SUDO_ASKPASS`:
When this variable is set, Homebrew-Cask will call `sudo`(8) with the `-A` option.
diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb
index 7ecdafe2f..0eb7492df 100644
--- a/Library/Homebrew/migrator.rb
+++ b/Library/Homebrew/migrator.rb
@@ -100,7 +100,7 @@ class Migrator
begin
migrator = Migrator.new(formula)
migrator.migrate
- rescue Exception => e
+ rescue => e
onoe e
end
end
@@ -196,7 +196,7 @@ class Migrator
update_tabs
rescue Interrupt
ignore_interrupts { backup_oldname }
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "Error occurred while migrating."
puts e
puts e.backtrace if ARGV.debug?
@@ -304,7 +304,7 @@ class Migrator
puts
puts "You can try again using:"
puts " brew link #{formula.name}"
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "An unexpected error occurred during linking"
puts e
puts e.backtrace if ARGV.debug?
diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb
index 4d90ddb61..a3d182a2b 100644
--- a/Library/Homebrew/missing_formula.rb
+++ b/Library/Homebrew/missing_formula.rb
@@ -31,7 +31,7 @@ module Homebrew
#{Formatter.url("https://pip.readthedocs.io/en/stable/installing/")}
EOS
when "pil" then <<-EOS.undent
- Instead of PIL, consider `pip install pillow` or `brew install Homebrew/science/pillow`.
+ Instead of PIL, consider `pip2 install pillow`.
EOS
when "macruby" then <<-EOS.undent
MacRuby is not packaged and is on an indefinite development hiatus.
@@ -53,16 +53,7 @@ module Homebrew
ruin SSH's security.
EOS
when "gsutil" then <<-EOS.undent
- Install gsutil with `pip install gsutil`
- EOS
- when "clojure" then <<-EOS.undent
- Clojure isn't really a program but a library managed as part of a
- project and Leiningen is the user interface to that library.
-
- To install Clojure you should install Leiningen:
- brew install leiningen
- and then follow the tutorial:
- #{Formatter.url("https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md")}
+ Install gsutil with `pip2 install gsutil`
EOS
when "gfortran" then <<-EOS.undent
GNU Fortran is now provided as part of GCC, and can be installed with:
diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb
index dcb65d9f8..ed966c804 100644
--- a/Library/Homebrew/official_taps.rb
+++ b/Library/Homebrew/official_taps.rb
@@ -1,5 +1,4 @@
OFFICIAL_TAPS = %w[
- apache
nginx
php
science
@@ -17,6 +16,7 @@ OFFICIAL_CMD_TAPS = {
}.freeze
DEPRECATED_OFFICIAL_TAPS = %w[
+ apache
binary
completions
devel-only
diff --git a/Library/Homebrew/options.rb b/Library/Homebrew/options.rb
index 9f1253531..05dd643ff 100644
--- a/Library/Homebrew/options.rb
+++ b/Library/Homebrew/options.rb
@@ -69,29 +69,29 @@ class Options
@options.each(*args, &block)
end
- def <<(o)
- @options << o
+ def <<(other)
+ @options << other
self
end
- def +(o)
- self.class.new(@options + o)
+ def +(other)
+ self.class.new(@options + other)
end
- def -(o)
- self.class.new(@options - o)
+ def -(other)
+ self.class.new(@options - other)
end
- def &(o)
- self.class.new(@options & o)
+ def &(other)
+ self.class.new(@options & other)
end
- def |(o)
- self.class.new(@options | o)
+ def |(other)
+ self.class.new(@options | other)
end
- def *(arg)
- @options.to_a * arg
+ def *(other)
+ @options.to_a * other
end
def empty?
diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb
index 5074665fc..853f75140 100644
--- a/Library/Homebrew/os/mac.rb
+++ b/Library/Homebrew/os/mac.rb
@@ -11,7 +11,7 @@ module OS
module Mac
module_function
- ::MacOS = self # rubocop:disable Style/ConstantName
+ ::MacOS = self # rubocop:disable Naming/ConstantName
raise "Loaded OS::Mac on generic OS!" if ENV["HOMEBREW_TEST_GENERIC_OS"]
@@ -34,12 +34,12 @@ module OS
def prerelease?
# TODO: bump version when new OS is released
- version >= "10.13"
+ version >= "10.14"
end
def outdated_release?
# TODO: bump version when new OS is released
- version < "10.10"
+ version < "10.11"
end
def cat
@@ -104,7 +104,7 @@ module OS
# Returns the path to an SDK or nil, following the rules set by #sdk.
def sdk_path(v = nil)
s = sdk(v)
- s.path unless s.nil?
+ s&.path
end
# See these issues for some history:
@@ -129,8 +129,8 @@ module OS
paths << path if path.exist?
end
- # Finally, some users make their MacPorts or Fink directorie
- # read-only in order to try out Homebrew, but this doens't work as
+ # Finally, some users make their MacPorts or Fink directories
+ # read-only in order to try out Homebrew, but this doesn't work as
# some build scripts error out when trying to read from these now
# unreadable paths.
%w[/sw /opt/local].map { |p| Pathname.new(p) }.each do |path|
@@ -229,7 +229,9 @@ module OS
end
def app_with_bundle_id(*ids)
- path = mdfind(*ids).first
+ path = mdfind(*ids)
+ .reject { |p| p.include?("/Backups.backupdb/") }
+ .first
Pathname.new(path) unless path.nil? || path.empty?
end
diff --git a/Library/Homebrew/os/mac/linkage_checker.rb b/Library/Homebrew/os/mac/linkage_checker.rb
index 786827852..f6aa4c2f3 100644
--- a/Library/Homebrew/os/mac/linkage_checker.rb
+++ b/Library/Homebrew/os/mac/linkage_checker.rb
@@ -5,7 +5,7 @@ require "formula"
class LinkageChecker
attr_reader :keg, :formula
attr_reader :brewed_dylibs, :system_dylibs, :broken_dylibs, :variable_dylibs
- attr_reader :undeclared_deps, :reverse_links
+ attr_reader :undeclared_deps, :unnecessary_deps, :reverse_links
def initialize(keg, formula = nil)
@keg = keg
@@ -16,6 +16,7 @@ class LinkageChecker
@variable_dylibs = Set.new
@undeclared_deps = []
@reverse_links = Hash.new { |h, k| h[k] = Set.new }
+ @unnecessary_deps = []
check_dylibs
end
@@ -51,7 +52,7 @@ class LinkageChecker
end
end
- @undeclared_deps = check_undeclared_deps if formula
+ @undeclared_deps, @unnecessary_deps = check_undeclared_deps if formula
end
def check_undeclared_deps
@@ -77,6 +78,12 @@ class LinkageChecker
a <=> b
end
end
+ unnecessary_deps = declared_dep_names.reject do |full_name|
+ name = full_name.split("/").last
+ next true if Formula[name].bin.directory?
+ @brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
+ end
+ [undeclared_deps, unnecessary_deps]
end
def display_normal_output
@@ -84,7 +91,8 @@ class LinkageChecker
display_items "Homebrew libraries", @brewed_dylibs
display_items "Variable-referenced libraries", @variable_dylibs
display_items "Missing libraries", @broken_dylibs
- display_items "Possible undeclared dependencies", @undeclared_deps
+ display_items "Undeclared dependencies with linkage", @undeclared_deps
+ display_items "Dependencies with no linkage", @unnecessary_deps
end
def display_reverse_output
@@ -102,6 +110,7 @@ class LinkageChecker
def display_test_output
display_items "Missing libraries", @broken_dylibs
+ display_items "Possible unnecessary dependencies", @unnecessary_deps
puts "No broken dylib links" if @broken_dylibs.empty?
end
@@ -113,6 +122,10 @@ class LinkageChecker
!@undeclared_deps.empty?
end
+ def unnecessary_deps?
+ !@unnecessary_deps.empty?
+ end
+
private
# Whether or not dylib is a harmless broken link, meaning that it's
diff --git a/Library/Homebrew/os/mac/version.rb b/Library/Homebrew/os/mac/version.rb
index 89016bb4d..db6dfcb1a 100644
--- a/Library/Homebrew/os/mac/version.rb
+++ b/Library/Homebrew/os/mac/version.rb
@@ -12,6 +12,7 @@ module OS
mountain_lion: "10.8",
lion: "10.7",
snow_leopard: "10.6",
+ leopard_64: "10.5",
leopard: "10.5",
tiger: "10.4",
}.freeze
diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb
index e23a7cf3d..5071aafcf 100644
--- a/Library/Homebrew/os/mac/xcode.rb
+++ b/Library/Homebrew/os/mac/xcode.rb
@@ -183,7 +183,7 @@ module OS
end
module CLT
- extend self
+ module_function
STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo".freeze
FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI".freeze
@@ -216,7 +216,7 @@ module OS
# on the older supported platform for that Xcode release, i.e there's no
# CLT package for 10.11 that contains the Clang version from Xcode 8.
case MacOS.version
- when "10.13" then "900.0.31"
+ when "10.13" then "900.0.37"
when "10.12" then "802.0.42"
when "10.11" then "800.0.42.1"
when "10.10" then "700.1.81"
diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb
index 7045adf5e..8a1b00930 100644
--- a/Library/Homebrew/patch.rb
+++ b/Library/Homebrew/patch.rb
@@ -60,8 +60,7 @@ class EmbeddedPatch
false
end
- def contents
- end
+ def contents; end
def apply
data = contents.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX)
@@ -87,10 +86,13 @@ class DATAPatch < EmbeddedPatch
def contents
data = ""
path.open("rb") do |f|
- begin
+ loop do
line = f.gets
- end until line.nil? || line =~ /^__END__$/
- data << line while line = f.gets
+ break if line.nil? || line =~ /^__END__$/
+ end
+ while line = f.gets
+ data << line
+ end
end
data
end
diff --git a/Library/Homebrew/pkg_version.rb b/Library/Homebrew/pkg_version.rb
index 761a349fd..b68d78cf8 100644
--- a/Library/Homebrew/pkg_version.rb
+++ b/Library/Homebrew/pkg_version.rb
@@ -23,7 +23,7 @@ class PkgVersion
end
def to_s
- if revision > 0
+ if revision.positive?
"#{version}_#{revision}"
else
version.to_s
diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb
index 0b6d8f6b0..53a5b7e75 100644
--- a/Library/Homebrew/postinstall.rb
+++ b/Library/Homebrew/postinstall.rb
@@ -14,7 +14,7 @@ begin
formula = ARGV.resolved_formulae.first
formula.extend(Debrew::Formula) if ARGV.debug?
formula.run_post_install
-rescue Exception => e
+rescue Exception => e # rubocop:disable Lint/RescueException
Marshal.dump(e, error_pipe)
error_pipe.close
exit! 1
diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb
index 3595c16be..5f4fd947c 100644
--- a/Library/Homebrew/readall.rb
+++ b/Library/Homebrew/readall.rb
@@ -52,7 +52,7 @@ module Readall
Formulary.factory(file)
rescue Interrupt
raise
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
onoe "Invalid formula: #{file}"
puts e
failed = true
diff --git a/Library/Homebrew/requirements/gpg2_requirement.rb b/Library/Homebrew/requirements/gpg2_requirement.rb
index 97fabcca0..ebdd71f6e 100644
--- a/Library/Homebrew/requirements/gpg2_requirement.rb
+++ b/Library/Homebrew/requirements/gpg2_requirement.rb
@@ -5,8 +5,8 @@ class GPG2Requirement < Requirement
fatal true
default_formula "gnupg"
- # MacGPG2/GPGTools installs GnuPG 2.0.x as a vanilla `gpg` symlink
- # pointing to `gpg2`, as do we. Ensure we're actually using a 2.0 `gpg`.
- # Support both the 2.0.x "stable" and 2.1.x "modern" series.
- satisfy(build_env: false) { Gpg.gpg2 || Gpg.gpg }
+ # GPGTools installs GnuPG 2.0.x as a `gpg` symlink pointing
+ # to `gpg2`. Our `gnupg` installs only a non-symlink `gpg`.
+ # The aim is to retain support for any version above 2.0.
+ satisfy(build_env: false) { Gpg.gpg || Gpg.gpg2 }
end
diff --git a/Library/Homebrew/requirements/java_requirement.rb b/Library/Homebrew/requirements/java_requirement.rb
index ab6dca51d..de3a33eb4 100644
--- a/Library/Homebrew/requirements/java_requirement.rb
+++ b/Library/Homebrew/requirements/java_requirement.rb
@@ -69,14 +69,14 @@ class JavaRequirement < Requirement
rescue FormulaUnavailableError
nil
end
- javas << jdk.bin/"java" if jdk && jdk.installed?
+ javas << jdk.bin/"java" if jdk&.installed?
javas << which("java")
javas
end
def preferred_java
possible_javas.detect do |java|
- next false unless java && java.executable?
+ next false unless java&.executable?
next true unless @version
next true if satisfies_version(java)
end
diff --git a/Library/Homebrew/requirements/ruby_requirement.rb b/Library/Homebrew/requirements/ruby_requirement.rb
index acc655924..a9ec8c42d 100644
--- a/Library/Homebrew/requirements/ruby_requirement.rb
+++ b/Library/Homebrew/requirements/ruby_requirement.rb
@@ -41,9 +41,7 @@ class RubyRequirement < Requirement
def rubies
rubies = which_all("ruby")
ruby_formula = Formula["ruby"]
- if ruby_formula && ruby_formula.installed?
- rubies.unshift ruby_formula.bin/"ruby"
- end
+ rubies.unshift ruby_formula.bin/"ruby" if ruby_formula&.installed?
rubies.uniq
end
diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb
index b1144e075..8dc49bb45 100644
--- a/Library/Homebrew/rubocops.rb
+++ b/Library/Homebrew/rubocops.rb
@@ -11,3 +11,4 @@ require_relative "./rubocops/conflicts_cop"
require_relative "./rubocops/options_cop"
require_relative "./rubocops/urls_cop"
require_relative "./rubocops/lines_cop"
+require_relative "./rubocops/class_cop"
diff --git a/Library/Homebrew/rubocops/class_cop.rb b/Library/Homebrew/rubocops/class_cop.rb
new file mode 100644
index 000000000..dad81abfc
--- /dev/null
+++ b/Library/Homebrew/rubocops/class_cop.rb
@@ -0,0 +1,41 @@
+require_relative "./extend/formula_cop"
+
+module RuboCop
+ module Cop
+ module FormulaAudit
+ class ClassName < FormulaCop
+ DEPRECATED_CLASSES = %w[
+ GithubGistFormula
+ ScriptFileFormula
+ AmazonWebServicesFormula
+ ].freeze
+
+ def audit_formula(_node, _class_node, parent_class_node, _body_node)
+ parent_class = class_name(parent_class_node)
+ return unless DEPRECATED_CLASSES.include?(parent_class)
+ problem "#{parent_class} is deprecated, use Formula instead"
+ end
+
+ private
+
+ def autocorrect(node)
+ lambda do |corrector|
+ corrector.replace(node.source_range, "Formula")
+ end
+ end
+ end
+ end
+
+ module FormulaAuditStrict
+ # - `test do ..end` should be defined in the formula
+ class Test < FormulaCop
+ MSG = "A `test do` test block should be added".freeze
+
+ def audit_formula(_node, _class_node, _parent_class_node, body_node)
+ return if find_block(body_node, :test)
+ problem MSG
+ end
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/rubocops/components_order_cop.rb b/Library/Homebrew/rubocops/components_order_cop.rb
index f1179d9a4..3bf2ede16 100644
--- a/Library/Homebrew/rubocops/components_order_cop.rb
+++ b/Library/Homebrew/rubocops/components_order_cop.rb
@@ -87,8 +87,8 @@ module RuboCop
# preceding_comp_arr: array containing components of same type
order_idx, curr_p_idx, preceding_comp_arr = get_state(node1)
- # curr_p_idx > 0 means node1 needs to be grouped with its own kind
- if curr_p_idx > 0
+ # curr_p_idx.positive? means node1 needs to be grouped with its own kind
+ if curr_p_idx.positive?
node2 = preceding_comp_arr[curr_p_idx - 1]
indentation = " " * (start_column(node2) - line_start_column(node2))
line_breaks = node2.multiline? ? "\n\n" : "\n"
diff --git a/Library/Homebrew/rubocops/conflicts_cop.rb b/Library/Homebrew/rubocops/conflicts_cop.rb
index c1b801559..6f05d0567 100644
--- a/Library/Homebrew/rubocops/conflicts_cop.rb
+++ b/Library/Homebrew/rubocops/conflicts_cop.rb
@@ -18,7 +18,7 @@ module RuboCop
def audit_formula(_node, _class_node, _parent_class_node, body)
return unless versioned_formula?
- problem MSG if !formula_file_name.start_with?(*WHITELIST) &&
+ problem MSG if !@formula_name.start_with?(*WHITELIST) &&
method_called_ever?(body, :conflicts_with)
end
end
diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb
index 76c7e43e9..63c75194c 100644
--- a/Library/Homebrew/rubocops/extend/formula_cop.rb
+++ b/Library/Homebrew/rubocops/extend/formula_cop.rb
@@ -1,4 +1,5 @@
require "parser/current"
+require_relative "../../extend/string"
module RuboCop
module Cop
@@ -13,7 +14,7 @@ module RuboCop
return unless formula_class?(node)
return unless respond_to?(:audit_formula)
class_node, parent_class_node, @body = *node
- @formula_name = class_name(class_node)
+ @formula_name = Pathname.new(@file_path).basename(".rb").to_s
audit_formula(node, class_node, parent_class_node, @body)
end
@@ -110,11 +111,15 @@ module RuboCop
# Matches a method with a receiver,
# EX: to match `Formula.factory(name)`
# call `find_instance_method_call(node, "Formula", :factory)`
+ # EX: to match `build.head?`
+ # call `find_instance_method_call(node, :build, :head?)`
# yields to a block with matching method node
def find_instance_method_call(node, instance, method_name)
methods = find_every_method_call_by_name(node, method_name)
methods.each do |method|
- next unless method.receiver && (method.receiver.const_name == instance || method.receiver.method_name == instance)
+ next if method.receiver.nil?
+ next if method.receiver.const_name != instance &&
+ method.receiver.method_name != instance
@offense_source_range = method.source_range
@offensive_node = method
return true unless block_given?
@@ -146,17 +151,14 @@ module RuboCop
case type
when :required
- type_match = !node.method_args.nil? &&
- (node.method_args.first.str_type? || node.method_args.first.sym_type?)
+ type_match = required_dependency?(node)
if type_match && !name_match
- name_match = node_equals?(node.method_args.first, name)
+ name_match = required_dependency_name?(node, name)
end
when :build, :optional, :recommended, :run
- type_match = !node.method_args.nil? &&
- node.method_args.first.hash_type? &&
- node.method_args.first.values.first.children.first == type
+ type_match = dependency_type_hash_match?(node, type)
if type_match && !name_match
- name_match = node_equals?(node.method_args.first.keys.first.children.first, name)
+ name_match = dependency_name_hash_match?(node, name)
end
else
type_match = false
@@ -183,6 +185,22 @@ module RuboCop
nil
end
+ def_node_search :required_dependency?, <<-EOS.undent
+ (send nil :depends_on ({str sym} _))
+ EOS
+
+ def_node_search :required_dependency_name?, <<-EOS.undent
+ (send nil :depends_on ({str sym} %1))
+ EOS
+
+ def_node_search :dependency_type_hash_match?, <<-EOS.undent
+ (hash (pair ({str sym} _) ({str sym} %1)))
+ EOS
+
+ def_node_search :dependency_name_hash_match?, <<-EOS.undent
+ (hash (pair ({str sym} %1) ({str sym} _)))
+ EOS
+
# To compare node with appropriate Ruby variable
def node_equals?(node, var)
node == Parser::CurrentRuby.parse(var.inspect)
@@ -309,7 +327,7 @@ module RuboCop
# Returns the array of arguments of the method_node
def parameters(method_node)
- method_node.method_args if method_node.send_type? || method_node.block_type?
+ method_node.arguments if method_node.send_type? || method_node.block_type?
end
# Returns true if the given parameters are present in method call
@@ -415,12 +433,7 @@ module RuboCop
# Returns true if the formula is versioned
def versioned_formula?
- formula_file_name.include?("@") || @formula_name.match(/AT\d+/)
- end
-
- # Returns filename of the formula without the extension
- def formula_file_name
- File.basename(processed_source.buffer.name, ".rb")
+ @formula_name.include?("@")
end
# Returns printable component name
@@ -443,7 +456,14 @@ module RuboCop
def formula_class?(node)
_, class_node, = *node
- class_node && string_content(class_node) == "Formula"
+ class_names = %w[
+ Formula
+ GithubGistFormula
+ ScriptFileFormula
+ AmazonWebServicesFormula
+ ]
+
+ class_node && class_names.include?(string_content(class_node))
end
def file_path_allowed?
diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb
index ef199fb6e..97bc45bc0 100644
--- a/Library/Homebrew/rubocops/lines_cop.rb
+++ b/Library/Homebrew/rubocops/lines_cop.rb
@@ -22,19 +22,12 @@ module RuboCop
begin_pos = start_column(parent_class_node)
end_pos = end_column(class_node)
return unless begin_pos-end_pos != 3
- problem "Use a space in class inheritance: class #{@formula_name} < #{class_name(parent_class_node)}"
+ problem "Use a space in class inheritance: class #{@formula_name.capitalize} < #{class_name(parent_class_node)}"
end
end
class Comments < FormulaCop
def audit_formula(_node, _class_node, _parent_class_node, _body_node)
- # Commented-out cmake support from default template
- audit_comments do |comment|
- next unless comment.include?('# system "cmake')
- problem "Commented cmake call found"
- end
-
- # Comments from default template
audit_comments do |comment|
[
"# PLEASE REMOVE",
@@ -45,6 +38,7 @@ module RuboCop
"# if your formula requires any X11/XQuartz components",
"# if your formula fails when building in parallel",
"# Remove unrecognized options if warned by configure",
+ '# system "cmake',
].each do |template_comment|
next unless comment.include?(template_comment)
problem "Please remove default template comments"
@@ -55,7 +49,7 @@ module RuboCop
audit_comments do |comment|
# Commented-out depends_on
next unless comment =~ /#\s*depends_on\s+(.+)\s*$/
- problem "Commented-out dep #{Regexp.last_match(1)}"
+ problem "Commented-out dependency #{Regexp.last_match(1)}"
end
end
end
@@ -75,33 +69,33 @@ module RuboCop
problem "\"inreplace <filenames> do |s|\" is preferred over \"|#{block_arg.source}|\"."
end
- [:rebuild, :version_scheme].each do |m|
- find_method_with_args(body_node, m, 0) do
- problem "'#{m} 0' should be removed"
+ [:rebuild, :version_scheme].each do |method_name|
+ find_method_with_args(body_node, method_name, 0) do
+ problem "'#{method_name} 0' should be removed"
end
end
- [:mac?, :linux?].each do |m|
+ [:mac?, :linux?].each do |method_name|
next unless formula_tap == "homebrew-core"
- find_instance_method_call(body_node, "OS", m) do |check|
+ find_instance_method_call(body_node, "OS", method_name) do |check|
problem "Don't use #{check.source}; Homebrew/core only supports macOS"
end
end
- [:debug?, :verbose?, :value].each do |m|
- find_instance_method_call(body_node, "ARGV", m) do
+ [:debug?, :verbose?, :value].each do |method_name|
+ find_instance_method_call(body_node, "ARGV", method_name) do
problem "Use build instead of ARGV to check options"
end
end
- find_instance_method_call(body_node, :man, :+) do |m|
- next unless match = regex_match_group(parameters(m).first, %r{man[1-8]})
- problem "\"#{m.source}\" should be \"#{match[0]}\""
+ find_instance_method_call(body_node, :man, :+) do |method|
+ next unless match = regex_match_group(parameters(method).first, %r{man[1-8]})
+ problem "\"#{method.source}\" should be \"#{match[0]}\""
end
# Avoid hard-coding compilers
- find_every_method_call_by_name(body_node, :system).each do |m|
- param = parameters(m).first
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ param = parameters(method).first
if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?})
problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\""
elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?})
@@ -109,8 +103,8 @@ module RuboCop
end
end
- find_instance_method_call(body_node, "ENV", :[]=) do |m|
- param = parameters(m)[1]
+ find_instance_method_call(body_node, "ENV", :[]=) do |method|
+ param = parameters(method)[1]
if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?})
problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\""
elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?})
@@ -136,29 +130,29 @@ module RuboCop
end
end
- find_every_method_call_by_name(body_node, :depends_on).each do |m|
- key, value = destructure_hash(parameters(m).first)
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ key, value = destructure_hash(parameters(method).first)
next if (key.nil? || value.nil?)
next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)})
- problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`"
+ problem "#{match[1]} modules should be vendored rather than use deprecated #{method.source}`"
end
- find_every_method_call_by_name(body_node, :system).each do |m|
- next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?})
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ next unless match = regex_match_group(parameters(method).first, %r{(env|export)(\s+)?})
problem "Use ENV instead of invoking '#{match[1]}' to modify the environment"
end
- find_every_method_call_by_name(body_node, :depends_on).each do |m|
- next if modifier?(m.parent)
- param = parameters(m).first
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ next if modifier?(method.parent)
+ param = parameters(method).first
dep, option = hash_dep(param)
next if dep.nil? || option.nil?
offending_node(param)
problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}"
end
- find_instance_method_call(body_node, :version, :==) do |m|
- next unless parameters_passed?(m, "HEAD")
+ find_instance_method_call(body_node, :version, :==) do |method|
+ next unless parameters_passed?(method, "HEAD")
problem "Use 'build.head?' instead of inspecting 'version'"
end
@@ -167,8 +161,8 @@ module RuboCop
problem "Use `depends_on :fortran` instead of `ENV.fortran`"
end
- find_instance_method_call(body_node, "ARGV", :include?) do |m|
- param = parameters(m).first
+ find_instance_method_call(body_node, "ARGV", :include?) do |method|
+ param = parameters(method).first
next unless match = regex_match_group(param, %r{--(HEAD|devel)})
problem "Use \"if build.#{match[1].downcase}?\" instead"
end
@@ -202,14 +196,21 @@ module RuboCop
problem "'fails_with :llvm' is now a no-op so should be removed"
end
- find_method_with_args(body_node, :system, /^(otool|install_name_tool|lipo)$/) do
+ find_method_with_args(body_node, :system, /(otool|install_name_tool|lipo)/) do
+ next if @formula_name == "cctools"
problem "Use ruby-macho instead of calling #{@offensive_node.source}"
end
- #
- find_method_with_args(body_node, :system, /npm/, /install/) do |m|
- next if @formula_name =~ /^kibana(\@\d+(\.\d+)?)?$/
- problem "Use Language::Node for npm install args" unless languageNode?(m)
+
+ find_every_method_call_by_name(body_node, :system).each do |method_node|
+ # Skip Kibana: npm cache edge (see formula for more details)
+ next if @formula_name =~ /^kibana(\@\d+(\.\d+)?)?$/i
+ first_param, second_param = parameters(method_node)
+ next if !node_equals?(first_param, "npm") ||
+ !node_equals?(second_param, "install")
+ offending_node(method_node)
+ problem "Use Language::Node for npm install args" unless languageNodeModule?(method_node)
end
+
if find_method_def(body_node, :test)
problem "Use new-style test definitions (test do)"
end
@@ -219,12 +220,15 @@ module RuboCop
end
find_method_with_args(body_node, :skip_clean, :all) do
- problem "`skip_clean :all` is deprecated; brew no longer strips symbols\n" \
- "\tPass explicit paths to prevent Homebrew from removing empty folders."
+ problem <<-EOS.undent.chomp
+ `skip_clean :all` is deprecated; brew no longer strips symbols
+ Pass explicit paths to prevent Homebrew from removing empty folders.
+ EOS
end
find_instance_method_call(body_node, :build, :universal?) do
- problem "macOS has been 64-bit only so build.universal? is deprecated."
+ next if @formula_name == "wine"
+ problem "macOS has been 64-bit only since 10.6 so build.universal? is deprecated."
end
find_instance_method_call(body_node, "ENV", :universal_binary) do
@@ -235,85 +239,85 @@ module RuboCop
problem 'Use "depends_on :x11" instead of "ENV.x11"'
end
- find_every_method_call_by_name(body_node, :assert).each do |m|
- if method_called?(m, :include?) && !method_called?(m, :!)
+ find_every_method_call_by_name(body_node, :assert).each do |method|
+ if method_called?(method, :include?) && !method_called?(method, :!)
problem "Use `assert_match` instead of `assert ...include?`"
end
end
- find_every_method_call_by_name(body_node, :depends_on).each do |m|
- next unless method_called?(m, :new)
+ find_every_method_call_by_name(body_node, :depends_on).each do |method|
+ next unless method_called?(method, :new)
problem "`depends_on` can take requirement classes instead of instances"
end
os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?]
os.each do |version|
- find_instance_method_call(body_node, "MacOS", version) do |m|
- problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead"
+ find_instance_method_call(body_node, "MacOS", version) do |method|
+ problem "\"#{method.source}\" is deprecated, use a comparison to MacOS.version instead"
end
end
- find_instance_method_call(body_node, "Dir", :[]) do |m|
- path = parameters(m).first
+ find_instance_method_call(body_node, "Dir", :[]) do |method|
+ path = parameters(method).first
next if !path.str_type?
next unless match = regex_match_group(path, /^[^\*{},]+$/)
problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\""
end
- fileUtils_methods= Regexp.new(FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|")
- find_every_method_call_by_name(body_node, :system).each do |m|
- param = parameters(m).first
+ fileUtils_methods= Regexp.new(FileUtils.singleton_methods(false).map { |m| '(?-mix:^'+Regexp.escape(m)+'$)' }.join '|')
+ find_every_method_call_by_name(body_node, :system).each do |method|
+ param = parameters(method).first
next unless match = regex_match_group(param, fileUtils_methods)
- problem "Use the `#{match}` Ruby method instead of `#{m.source}`"
+ problem "Use the `#{match}` Ruby method instead of `#{method.source}`"
end
if find_method_def(@processed_source.ast)
problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level"
end
- find_instance_method_call(body_node, :build, :without?) do |m|
- next unless unless_modifier?(m.parent)
- correct = m.source.gsub("out?", "?")
- problem "Use if #{correct} instead of unless #{m.source}"
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ next unless unless_modifier?(method.parent)
+ correct = method.source.gsub("out?", "?")
+ problem "Use if #{correct} instead of unless #{method.source}"
end
- find_instance_method_call(body_node, :build, :with?) do |m|
- next unless unless_modifier?(m.parent)
- correct = m.source.gsub("?", "out?")
- problem "Use if #{correct} instead of unless #{m.source}"
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ next unless unless_modifier?(method.parent)
+ correct = method.source.gsub("?", "out?")
+ problem "Use if #{correct} instead of unless #{method.source}"
end
- find_instance_method_call(body_node, :build, :with?) do |m|
- next unless negated?(m.parent)
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ next unless negated?(method.parent)
problem "Don't negate 'build.with?': use 'build.without?'"
end
- find_instance_method_call(body_node, :build, :without?) do |m|
- next unless negated?(m.parent)
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ next unless negated?(method.parent)
problem "Don't negate 'build.without?': use 'build.with?'"
end
- find_instance_method_call(body_node, :build, :without?) do |m|
- arg = parameters(m).first
+ find_instance_method_call(body_node, :build, :without?) do |method|
+ arg = parameters(method).first
next unless match = regex_match_group(arg, %r{-?-?without-(.*)})
problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\""
end
- find_instance_method_call(body_node, :build, :with?) do |m|
- arg = parameters(m).first
+ find_instance_method_call(body_node, :build, :with?) do |method|
+ arg = parameters(method).first
next unless match = regex_match_group(arg, %r{-?-?with-(.*)})
problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\""
end
- find_instance_method_call(body_node, :build, :include?) do |m|
- arg = parameters(m).first
+ find_instance_method_call(body_node, :build, :include?) do |method|
+ arg = parameters(method).first
next unless match = regex_match_group(arg, %r{with(out)?-(.*)})
problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'"
end
- find_instance_method_call(body_node, :build, :include?) do |m|
- arg = parameters(m).first
+ find_instance_method_call(body_node, :build, :include?) do |method|
+ arg = parameters(method).first
next unless match = regex_match_group(arg, %r{\-\-(.*)})
problem "Reference '#{match[1]}' without dashes"
end
@@ -352,19 +356,11 @@ module RuboCop
(dstr _ (begin (send nil %1)) $(str _ ))}
EOS
- # This is Pattern Matching method for AST
- # Takes the AST node as argument and yields matching node if block given
- # Else returns boolean for the match
- def_node_search :languageNode?, <<-PATTERN
+ # Node Pattern search for Language::Node
+ def_node_search :languageNodeModule?, <<-EOS.undent
(const (const nil :Language) :Node)
- PATTERN
-
+ EOS
end
end
end
end
-
-# Strict rules ported early
-# find_method_with_args(@processed_source.ast, :require, "formula") do |m|
-# problem "#{m.source} is now unnecessary"
-# end
diff --git a/Library/Homebrew/rubocops/patches_cop.rb b/Library/Homebrew/rubocops/patches_cop.rb
index fb14d8acc..7ee1a127a 100644
--- a/Library/Homebrew/rubocops/patches_cop.rb
+++ b/Library/Homebrew/rubocops/patches_cop.rb
@@ -25,13 +25,26 @@ module RuboCop
def patch_problems(patch)
patch_url = string_content(patch)
+ gh_patch_param_pattern = %r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)}
+ if regex_match_group(patch, gh_patch_param_pattern)
+ if patch_url !~ /\?full_index=\w+$/
+ problem <<-EOS.undent
+ GitHub patches should use the full_index parameter:
+ #{patch_url}?full_index=1
+ EOS
+ end
+ end
+
gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/},
%r{gist\.github\.com/raw},
%r{gist\.github\.com/.+/raw},
%r{gist\.githubusercontent\.com/.+/raw}])
if regex_match_group(patch, gh_patch_patterns)
- unless patch_url =~ /[a-fA-F0-9]{40}/
- problem "GitHub/Gist patches should specify a revision:\n#{patch_url}"
+ if patch_url !~ /[a-fA-F0-9]{40}/
+ problem <<-EOS.undent.chomp
+ GitHub/Gist patches should specify a revision:
+ #{patch_url}
+ EOS
end
end
@@ -46,15 +59,24 @@ module RuboCop
end
if regex_match_group(patch, %r{macports/trunk})
- problem "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}"
+ problem <<-EOS.undent.chomp
+ MacPorts patches should specify a revision instead of trunk:
+ #{patch_url}
+ EOS
end
if regex_match_group(patch, %r{^http://trac\.macports\.org})
- problem "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}"
+ problem <<-EOS.undent.chomp
+ Patches from MacPorts Trac should be https://, not http:
+ #{patch_url}
+ EOS
end
return unless regex_match_group(patch, %r{^http://bugs\.debian\.org})
- problem "Patches from Debian should be https://, not http:\n#{patch_url}"
+ problem <<-EOS.undent.chomp
+ Patches from Debian should be https://, not http:
+ #{patch_url}
+ EOS
end
end
end
diff --git a/Library/Homebrew/rubocops/urls_cop.rb b/Library/Homebrew/rubocops/urls_cop.rb
index 676e73523..071a4c42d 100644
--- a/Library/Homebrew/rubocops/urls_cop.rb
+++ b/Library/Homebrew/rubocops/urls_cop.rb
@@ -104,8 +104,10 @@ module RuboCop
end
if url =~ %r{^https?://prdownloads\.}
- problem "Don't use prdownloads in SourceForge urls (url is #{url}).\n" \
- "\tSee: http://librelist.com/browser/homebrew/2011/1/12/prdownloads-is-bad/"
+ problem <<-EOS.undent.chomp
+ Don't use prdownloads in SourceForge urls (url is #{url}).
+ See: http://librelist.com/browser/homebrew/2011/1/12/prdownloads-is-bad/
+ EOS
end
if url =~ %r{^http://\w+\.dl\.}
diff --git a/Library/Homebrew/sandbox.rb b/Library/Homebrew/sandbox.rb
index 0de970773..7d23e5966 100644
--- a/Library/Homebrew/sandbox.rb
+++ b/Library/Homebrew/sandbox.rb
@@ -18,12 +18,6 @@ class Sandbox
!ARGV.no_sandbox?
end
- def self.print_sandbox_message
- return if @printed_sandbox_message
- ohai "Using the sandbox"
- @printed_sandbox_message = true
- end
-
def initialize
@profile = SandboxProfile.new
end
@@ -173,7 +167,7 @@ class Sandbox
def add_rule(rule)
s = "("
- s << ((rule[:allow]) ? "allow" : "deny")
+ s << (rule[:allow] ? "allow" : "deny")
s << " #{rule[:operation]}"
s << " (#{rule[:filter]})" if rule[:filter]
s << " (with #{rule[:modifier]})" if rule[:modifier]
diff --git a/Library/Homebrew/shims/super/cc b/Library/Homebrew/shims/super/cc
index d894d3d69..afe72156f 100755
--- a/Library/Homebrew/shims/super/cc
+++ b/Library/Homebrew/shims/super/cc
@@ -43,6 +43,8 @@ class Cmd
else
:cc
end
+ elsif @args.include?("-xc++-header") || @args.each_cons(2).include?(["-x", "c++-header"])
+ :cxx
elsif @args.include? "-E"
:ccE
else
diff --git a/Library/Homebrew/shims/super/make b/Library/Homebrew/shims/super/make
index 7b49e56c0..46de53131 100755
--- a/Library/Homebrew/shims/super/make
+++ b/Library/Homebrew/shims/super/make
@@ -1,5 +1,10 @@
#!/bin/bash
-export MAKE=${HOMEBREW_MAKE:-make}
+if [[ -n "$HOMEBREW_MAKE" && "$HOMEBREW_MAKE" != "make" ]]
+then
+ export MAKE="$HOMEBREW_MAKE"
+else
+ MAKE="make"
+fi
export HOMEBREW_CCCFG="O$HOMEBREW_CCCFG"
-exec xcrun $MAKE "$@"
+exec xcrun "$MAKE" "$@"
diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb
index c6e704350..dd6026fcf 100644
--- a/Library/Homebrew/software_spec.rb
+++ b/Library/Homebrew/software_spec.rb
@@ -51,8 +51,18 @@ class SoftwareSpec
@owner = owner
@resource.owner = self
resources.each_value do |r|
- r.owner = self
- r.version ||= (version.head? ? Version.create("HEAD") : version.dup)
+ r.owner = self
+ r.version ||= begin
+ if version.nil?
+ raise "#{full_name}: version missing for \"#{r.name}\" resource!"
+ end
+
+ if version.head?
+ Version.create("HEAD")
+ else
+ version.dup
+ end
+ end
end
patches.each { |p| p.owner = self }
end
@@ -257,7 +267,7 @@ class Bottle
end
def suffix
- s = (rebuild > 0) ? ".#{rebuild}" : ""
+ s = rebuild.positive? ? ".#{rebuild}" : ""
".bottle#{s}.tar.gz"
end
end
diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb
index 5663295c2..3e1acd4ff 100644
--- a/Library/Homebrew/system_config.rb
+++ b/Library/Homebrew/system_config.rb
@@ -134,7 +134,7 @@ class SystemConfig
# java_home doesn't exist on all macOSs; it might be missing on older versions.
return "N/A" unless File.executable? "/usr/libexec/java_home"
- java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast")
+ java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast", err: :close)
return "N/A" unless $CHILD_STATUS.success?
javas = []
REXML::XPath.each(REXML::Document.new(java_xml), "//key[text()='JVMVersion']/following-sibling::string") do |item|
diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb
index e7df88356..aa0208d51 100644
--- a/Library/Homebrew/tab.rb
+++ b/Library/Homebrew/tab.rb
@@ -3,18 +3,16 @@ require "ostruct"
require "options"
require "json"
require "development_tools"
+require "extend/cachable"
# Inherit from OpenStruct to gain a generic initialization method that takes a
# hash and creates an attribute for each key and value. `Tab.new` probably
# should not be called directly, instead use one of the class methods like
# `Tab.create`.
class Tab < OpenStruct
- FILENAME = "INSTALL_RECEIPT.json".freeze
- CACHE = {}
+ extend Cachable
- def self.clear_cache
- CACHE.clear
- end
+ FILENAME = "INSTALL_RECEIPT.json".freeze
# Instantiates a Tab for a new installation of a formula.
def self.create(formula, compiler, stdlib)
@@ -57,7 +55,7 @@ class Tab < OpenStruct
# Returns the Tab for an install receipt at `path`.
# Results are cached.
def self.from_file(path)
- CACHE.fetch(path) { |p| CACHE[p] = from_file_content(File.read(p), p) }
+ cache.fetch(path) { |p| cache[p] = from_file_content(File.read(p), p) }
end
# Like Tab.from_file, but bypass the cache.
@@ -324,7 +322,7 @@ class Tab < OpenStruct
"poured_from_bottle" => poured_from_bottle,
"installed_as_dependency" => installed_as_dependency,
"installed_on_request" => installed_on_request,
- "changed_files" => changed_files && changed_files.map(&:to_s),
+ "changed_files" => changed_files&.map(&:to_s),
"time" => time,
"source_modified_time" => source_modified_time.to_i,
"HEAD" => self.HEAD,
@@ -343,7 +341,7 @@ class Tab < OpenStruct
# will no longer be valid.
Formula.clear_installed_formulae_cache unless tabfile.exist?
- CACHE[tabfile] = self
+ self.class.cache[tabfile] = self
tabfile.atomic_write(to_json)
end
diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb
index f232be428..78dc4cf4e 100644
--- a/Library/Homebrew/tap.rb
+++ b/Library/Homebrew/tap.rb
@@ -1,4 +1,5 @@
require "extend/string"
+require "extend/cachable"
require "readall"
# a {Tap} is used to extend the formulae provided by Homebrew core.
@@ -8,13 +9,9 @@ require "readall"
# {#user} represents Github username and {#repo} represents repository
# name without leading `homebrew-`.
class Tap
- TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps"
-
- CACHE = {}
+ extend Cachable
- def self.clear_cache
- CACHE.clear
- end
+ TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps"
def self.fetch(*args)
case args.length
@@ -38,7 +35,7 @@ class Tap
end
cache_key = "#{user}/#{repo}".downcase
- CACHE.fetch(cache_key) { |key| CACHE[key] = Tap.new(user, repo) }
+ cache.fetch(cache_key) { |key| cache[key] = Tap.new(user, repo) }
end
def self.from_path(path)
@@ -551,11 +548,9 @@ class CoreTap < Tap
@instance ||= new
end
- def self.ensure_installed!(options = {})
+ def self.ensure_installed!
return if instance.installed?
- args = ["tap", instance.name]
- args << "-q" if options.fetch(:quiet, true)
- safe_system HOMEBREW_BREW_FILE, *args
+ safe_system HOMEBREW_BREW_FILE, "tap", instance.name
end
# @private
@@ -650,6 +645,5 @@ class TapConfig
tap.path.cd do
safe_system "git", "config", "--local", "--replace-all", "homebrew.#{key}", value.to_s
end
- value
end
end
diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb
index d9ec8250e..3d5e62a88 100644
--- a/Library/Homebrew/test.rb
+++ b/Library/Homebrew/test.rb
@@ -27,7 +27,7 @@ begin
Timeout.timeout TEST_TIMEOUT_SECONDS do
raise "test returned false" if formula.run_test == false
end
-rescue Exception => e
+rescue Exception => e # rubocop:disable Lint/RescueException
Marshal.dump(e, error_pipe)
error_pipe.close
exit! 1
diff --git a/Library/Homebrew/test/Gemfile b/Library/Homebrew/test/Gemfile
index dbe76b51c..b6d1405ff 100644
--- a/Library/Homebrew/test/Gemfile
+++ b/Library/Homebrew/test/Gemfile
@@ -1,10 +1,12 @@
source "https://rubygems.org"
+require_relative "../constants"
+
gem "parallel_tests"
gem "rspec"
gem "rspec-its", require: false
gem "rspec-wait", require: false
-gem "rubocop"
+gem "rubocop", HOMEBREW_RUBOCOP_VERSION
group :coverage do
gem "codecov", require: false
diff --git a/Library/Homebrew/test/Gemfile.lock b/Library/Homebrew/test/Gemfile.lock
index ccfd91542..ba12d091d 100644
--- a/Library/Homebrew/test/Gemfile.lock
+++ b/Library/Homebrew/test/Gemfile.lock
@@ -9,15 +9,15 @@ GEM
diff-lcs (1.3)
docile (1.1.5)
json (2.1.0)
- parallel (1.11.2)
- parallel_tests (2.14.1)
+ parallel (1.12.0)
+ parallel_tests (2.17.0)
parallel
parser (2.4.0.0)
ast (~> 2.2)
powerpack (0.1.1)
rainbow (2.2.2)
rake
- rake (12.0.0)
+ rake (12.1.0)
rspec (3.6.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
@@ -36,20 +36,20 @@ GEM
rspec-support (3.6.0)
rspec-wait (0.0.9)
rspec (>= 3, < 4)
- rubocop (0.49.1)
+ rubocop (0.50.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1)
- rainbow (>= 1.99.1, < 3.0)
+ rainbow (>= 2.2.2, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
- ruby-progressbar (1.8.1)
- simplecov (0.14.1)
+ ruby-progressbar (1.9.0)
+ simplecov (0.15.1)
docile (~> 1.1.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
- simplecov-html (0.10.0)
- unicode-display_width (1.2.1)
+ simplecov-html (0.10.2)
+ unicode-display_width (1.3.0)
url (0.3.2)
PLATFORMS
@@ -61,8 +61,8 @@ DEPENDENCIES
rspec
rspec-its
rspec-wait
- rubocop
+ rubocop (= 0.50.0)
simplecov
BUNDLED WITH
- 1.14.6
+ 1.15.4
diff --git a/Library/Homebrew/test/bottle_hooks_spec.rb b/Library/Homebrew/test/bottle_hooks_spec.rb
index e70b558a1..eb6617380 100644
--- a/Library/Homebrew/test/bottle_hooks_spec.rb
+++ b/Library/Homebrew/test/bottle_hooks_spec.rb
@@ -8,7 +8,7 @@ describe Homebrew::Hooks::Bottles do
let(:formula) do
double(
- bottle: nil,
+ bottled?: false,
local_bottle_path: nil,
bottle_disabled?: false,
some_random_method: true,
diff --git a/Library/Homebrew/test/cask/accessibility_spec.rb b/Library/Homebrew/test/cask/accessibility_spec.rb
index 9e56f6bd3..b77bcb002 100644
--- a/Library/Homebrew/test/cask/accessibility_spec.rb
+++ b/Library/Homebrew/test/cask/accessibility_spec.rb
@@ -1,7 +1,7 @@
# TODO: this test should be named after the corresponding class, once
# that class is abstracted from installer.rb.
describe "Accessibility Access", :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-accessibility-access.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-accessibility-access")) }
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
let(:installer) { Hbc::Installer.new(cask, command: fake_system_command) }
diff --git a/Library/Homebrew/test/cask/artifact/alt_target_spec.rb b/Library/Homebrew/test/cask/artifact/alt_target_spec.rb
index 9e8d83bb4..847bf25fa 100644
--- a/Library/Homebrew/test/cask/artifact/alt_target_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/alt_target_spec.rb
@@ -1,9 +1,13 @@
describe Hbc::Artifact::App, :cask do
describe "activate to alternate target" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-alt-target.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-alt-target")) }
let(:install_phase) {
- -> { Hbc::Artifact::App.new(cask).install_phase }
+ lambda do
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
+ end
}
let(:source_path) { cask.staged_path.join("Caffeine.app") }
diff --git a/Library/Homebrew/test/cask/artifact/app_spec.rb b/Library/Homebrew/test/cask/artifact/app_spec.rb
index 0add472e2..4ead8b7f9 100644
--- a/Library/Homebrew/test/cask/artifact/app_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/app_spec.rb
@@ -1,14 +1,14 @@
describe Hbc::Artifact::App, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("local-caffeine")) }
let(:command) { Hbc::SystemCommand }
let(:force) { false }
- let(:app) { Hbc::Artifact::App.new(cask, command: command, force: force) }
+ let(:app) { cask.artifacts.find { |a| a.is_a?(described_class) } }
let(:source_path) { cask.staged_path.join("Caffeine.app") }
let(:target_path) { Hbc.appdir.join("Caffeine.app") }
- let(:install_phase) { app.install_phase }
- let(:uninstall_phase) { app.uninstall_phase }
+ let(:install_phase) { app.install_phase(command: command, force: force) }
+ let(:uninstall_phase) { app.uninstall_phase(command: command, force: force) }
before(:each) do
InstallHelper.install_without_artifacts(cask)
@@ -105,8 +105,8 @@ describe Hbc::Artifact::App, :cask do
describe "target is user-owned but contains read-only files" do
before(:each) do
- system "/usr/bin/touch", "--", "#{target_path}/foo"
- system "/bin/chmod", "--", "0555", target_path
+ FileUtils.touch "#{target_path}/foo"
+ FileUtils.chmod 0555, target_path
end
it "overwrites the existing app" do
@@ -138,7 +138,7 @@ describe Hbc::Artifact::App, :cask do
end
after(:each) do
- system "/bin/chmod", "--", "0755", target_path
+ FileUtils.chmod 0755, target_path
end
end
end
@@ -206,8 +206,8 @@ describe Hbc::Artifact::App, :cask do
end
describe "summary" do
- let(:description) { app.summary[:english_description] }
- let(:contents) { app.summary[:contents] }
+ let(:description) { app.class.english_description }
+ let(:contents) { app.summarize_installed }
it "returns the correct english_description" do
expect(description).to eq("Apps")
@@ -217,14 +217,13 @@ describe Hbc::Artifact::App, :cask do
it "returns the path to the app" do
install_phase
- expect(contents).to eq(["#{target_path} (#{target_path.abv})"])
+ expect(contents).to eq("#{target_path} (#{target_path.abv})")
end
end
describe "app is missing" do
it "returns a warning and the supposed path to the app" do
- expect(contents.size).to eq(1)
- expect(contents[0]).to match(/.*Missing App.*: #{target_path}/)
+ expect(contents).to match(/.*Missing App.*: #{target_path}/)
end
end
end
diff --git a/Library/Homebrew/test/cask/artifact/binary_spec.rb b/Library/Homebrew/test/cask/artifact/binary_spec.rb
index ce00e3935..6a3f1da34 100644
--- a/Library/Homebrew/test/cask/artifact/binary_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/binary_spec.rb
@@ -1,9 +1,10 @@
describe Hbc::Artifact::Binary, :cask do
let(:cask) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-binary.rb").tap do |cask|
+ Hbc::CaskLoader.load(cask_path("with-binary")).tap do |cask|
InstallHelper.install_without_artifacts(cask)
end
}
+ let(:artifacts) { cask.artifacts.select { |a| a.is_a?(described_class) } }
let(:expected_path) { Hbc.binarydir.join("binary") }
before(:each) do
@@ -16,7 +17,7 @@ describe Hbc::Artifact::Binary, :cask do
context "when --no-binaries is specified" do
let(:cask) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-binary.rb")
+ Hbc::CaskLoader.load(cask_path("with-binary"))
}
it "doesn't link the binary when --no-binaries is specified" do
@@ -26,7 +27,9 @@ describe Hbc::Artifact::Binary, :cask do
end
it "links the binary to the proper directory" do
- Hbc::Artifact::Binary.new(cask).install_phase
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(expected_path).to be_a_symlink
expect(expected_path.readlink).to exist
@@ -34,7 +37,7 @@ describe Hbc::Artifact::Binary, :cask do
context "when the binary is not executable" do
let(:cask) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-non-executable-binary.rb").tap do |cask|
+ Hbc::CaskLoader.load(cask_path("with-non-executable-binary")).tap do |cask|
InstallHelper.install_without_artifacts(cask)
end
}
@@ -45,7 +48,9 @@ describe Hbc::Artifact::Binary, :cask do
expect(FileUtils).to receive(:chmod)
.with("+x", cask.staged_path.join("naked_non_executable")).and_call_original
- Hbc::Artifact::Binary.new(cask).install_phase
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(expected_path).to be_a_symlink
expect(expected_path.readlink).to be_executable
@@ -56,7 +61,9 @@ describe Hbc::Artifact::Binary, :cask do
FileUtils.touch expected_path
expect {
- Hbc::Artifact::Binary.new(cask).install_phase
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
}.to raise_error(Hbc::CaskError)
expect(expected_path).not_to be :symlink?
@@ -65,7 +72,9 @@ describe Hbc::Artifact::Binary, :cask do
it "clobbers an existing symlink" do
expected_path.make_symlink("/tmp")
- Hbc::Artifact::Binary.new(cask).install_phase
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(File.readlink(expected_path)).not_to eq("/tmp")
end
@@ -73,21 +82,27 @@ describe Hbc::Artifact::Binary, :cask do
it "creates parent directory if it doesn't exist" do
FileUtils.rmdir Hbc.binarydir
- Hbc::Artifact::Binary.new(cask).install_phase
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(expected_path.exist?).to be true
end
context "binary is inside an app package" do
let(:cask) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-embedded-binary.rb").tap do |cask|
+ Hbc::CaskLoader.load(cask_path("with-embedded-binary")).tap do |cask|
InstallHelper.install_without_artifacts(cask)
end
}
it "links the binary to the proper directory" do
- Hbc::Artifact::App.new(cask).install_phase
- Hbc::Artifact::Binary.new(cask).install_phase
+ cask.artifacts.select { |a| a.is_a?(Hbc::Artifact::App) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
+ artifacts.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(expected_path).to be_a_symlink
expect(expected_path.readlink).to exist
diff --git a/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb b/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb
index cb2ef9850..ea567abee 100644
--- a/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb
@@ -1,8 +1,12 @@
describe Hbc::Artifact::Artifact, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-generic-artifact.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-generic-artifact")) }
let(:install_phase) {
- -> { Hbc::Artifact::Artifact.new(cask).install_phase }
+ lambda do
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
+ end
}
let(:source_path) { cask.staged_path.join("Caffeine.app") }
@@ -12,11 +16,11 @@ describe Hbc::Artifact::Artifact, :cask do
InstallHelper.install_without_artifacts(cask)
end
- describe "with no target" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-generic-artifact-no-target.rb") }
-
- it "fails to install with no target" do
- expect(install_phase).to raise_error(Hbc::CaskInvalidError)
+ context "without target" do
+ it "fails to load" do
+ expect {
+ Hbc::CaskLoader.load(cask_path("with-generic-artifact-no-target"))
+ }.to raise_error(Hbc::CaskInvalidError, /target required for Generic Artifact/)
end
end
diff --git a/Library/Homebrew/test/cask/artifact/nested_container_spec.rb b/Library/Homebrew/test/cask/artifact/nested_container_spec.rb
index be7ba5ff8..f9cd056f8 100644
--- a/Library/Homebrew/test/cask/artifact/nested_container_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/nested_container_spec.rb
@@ -1,11 +1,13 @@
describe Hbc::Artifact::NestedContainer, :cask do
describe "install" do
it "extracts the specified paths as containers" do
- cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/nested-app.rb").tap do |c|
+ cask = Hbc::CaskLoader.load(cask_path("nested-app")).tap do |c|
InstallHelper.install_without_artifacts(c)
end
- Hbc::Artifact::NestedContainer.new(cask).install_phase
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(cask.staged_path.join("MyNestedApp.app")).to be_a_directory
end
diff --git a/Library/Homebrew/test/cask/artifact/pkg_spec.rb b/Library/Homebrew/test/cask/artifact/pkg_spec.rb
index 3e62616ea..7f1b64d1a 100644
--- a/Library/Homebrew/test/cask/artifact/pkg_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/pkg_spec.rb
@@ -1,5 +1,5 @@
describe Hbc::Artifact::Pkg, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-installable.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-installable")) }
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
before(:each) do
@@ -8,7 +8,7 @@ describe Hbc::Artifact::Pkg, :cask do
describe "install_phase" do
it "runs the system installer on the specified pkgs" do
- pkg = Hbc::Artifact::Pkg.new(cask, command: fake_system_command)
+ pkg = cask.artifacts.find { |a| a.is_a?(described_class) }
expect(fake_system_command).to receive(:run!).with(
"/usr/sbin/installer",
@@ -17,15 +17,15 @@ describe Hbc::Artifact::Pkg, :cask do
print_stdout: true,
)
- pkg.install_phase
+ pkg.install_phase(command: fake_system_command)
end
end
describe "choices" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-choices.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-choices")) }
it "passes the choice changes xml to the system installer" do
- pkg = Hbc::Artifact::Pkg.new(cask, command: fake_system_command)
+ pkg = cask.artifacts.find { |a| a.is_a?(described_class) }
file = double(path: Pathname.new("/tmp/choices.xml"))
@@ -57,7 +57,7 @@ describe Hbc::Artifact::Pkg, :cask do
print_stdout: true,
)
- pkg.install_phase
+ pkg.install_phase(command: fake_system_command)
end
end
end
diff --git a/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb b/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb
index 51b1431f0..18cc4ca91 100644
--- a/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb
@@ -11,7 +11,9 @@ describe Hbc::Artifact::PostflightBlock, :cask do
end
end
- described_class.new(cask).install_phase
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(called).to be true
expect(yielded_arg).to be_kind_of(Hbc::DSL::Postflight)
@@ -30,7 +32,9 @@ describe Hbc::Artifact::PostflightBlock, :cask do
end
end
- described_class.new(cask).uninstall_phase
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.uninstall_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(called).to be true
expect(yielded_arg).to be_kind_of(Hbc::DSL::UninstallPostflight)
diff --git a/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb b/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb
index b13c4ab9d..405cdbd6f 100644
--- a/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb
@@ -11,7 +11,9 @@ describe Hbc::Artifact::PreflightBlock, :cask do
end
end
- described_class.new(cask).install_phase
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(called).to be true
expect(yielded_arg).to be_kind_of Hbc::DSL::Preflight
@@ -30,7 +32,9 @@ describe Hbc::Artifact::PreflightBlock, :cask do
end
end
- described_class.new(cask).uninstall_phase
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.uninstall_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect(called).to be true
expect(yielded_arg).to be_kind_of Hbc::DSL::UninstallPreflight
diff --git a/Library/Homebrew/test/cask/artifact/suite_spec.rb b/Library/Homebrew/test/cask/artifact/suite_spec.rb
index 8c217a9e0..80d3e917f 100644
--- a/Library/Homebrew/test/cask/artifact/suite_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/suite_spec.rb
@@ -1,7 +1,13 @@
describe Hbc::Artifact::Suite, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-suite.rb") }
-
- let(:install_phase) { -> { Hbc::Artifact::Suite.new(cask).install_phase } }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-suite")) }
+
+ let(:install_phase) {
+ lambda do
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
+ end
+ }
let(:target_path) { Hbc.appdir.join("Caffeine") }
let(:source_path) { cask.staged_path.join("Caffeine") }
diff --git a/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb b/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb
index a1fdd3b74..7f2ef75b3 100644
--- a/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb
@@ -1,9 +1,13 @@
describe Hbc::Artifact::App, :cask do
describe "multiple apps" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-two-apps-correct.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-two-apps-correct")) }
let(:install_phase) {
- -> { Hbc::Artifact::App.new(cask).install_phase }
+ lambda do
+ cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
+ end
}
let(:source_path_mini) { cask.staged_path.join("Caffeine Mini.app") }
@@ -27,7 +31,7 @@ describe Hbc::Artifact::App, :cask do
end
describe "when apps are in a subdirectory" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-two-apps-subdir.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-two-apps-subdir")) }
it "installs both apps using the proper target directory" do
install_phase.call
diff --git a/Library/Homebrew/test/cask/artifact/two_apps_incorrect_spec.rb b/Library/Homebrew/test/cask/artifact/two_apps_incorrect_spec.rb
index 6427ec32c..cda5b4488 100644
--- a/Library/Homebrew/test/cask/artifact/two_apps_incorrect_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/two_apps_incorrect_spec.rb
@@ -2,7 +2,7 @@ describe Hbc::Artifact::App, :cask do
# FIXME: Doesn't actually raise because the `app` stanza is not evaluated on load.
# it "must raise" do
# lambda {
- # Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-two-apps-incorrect.rb")
+ # Hbc::CaskLoader.load(cask_path("with-two-apps-incorrect"))
# }.must_raise
# # TODO: later give the user a nice exception for this case and check for it here
# end
diff --git a/Library/Homebrew/test/cask/artifact/uninstall_no_zap_spec.rb b/Library/Homebrew/test/cask/artifact/uninstall_no_zap_spec.rb
index 8cd0b1e41..c6ff7d30e 100644
--- a/Library/Homebrew/test/cask/artifact/uninstall_no_zap_spec.rb
+++ b/Library/Homebrew/test/cask/artifact/uninstall_no_zap_spec.rb
@@ -1,8 +1,8 @@
describe Hbc::Artifact::Zap, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-installable.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-installable")) }
let(:zap_artifact) {
- Hbc::Artifact::Zap.new(cask)
+ cask.artifacts.find { |a| a.is_a?(described_class) }
}
before(:each) do
diff --git a/Library/Homebrew/test/cask/artifact/uninstall_zap_shared_examples.rb b/Library/Homebrew/test/cask/artifact/uninstall_zap_shared_examples.rb
index 0e522bc21..b9872ab9e 100644
--- a/Library/Homebrew/test/cask/artifact/uninstall_zap_shared_examples.rb
+++ b/Library/Homebrew/test/cask/artifact/uninstall_zap_shared_examples.rb
@@ -1,12 +1,12 @@
shared_examples "#uninstall_phase or #zap_phase" do
- let(:artifact_name) { described_class.artifact_name }
- let(:artifact) { described_class.new(cask, command: fake_system_command) }
+ let(:artifact_dsl_key) { described_class.dsl_key }
+ let(:artifact) { cask.artifacts.find { |a| a.is_a?(described_class) } }
let(:fake_system_command) { Hbc::FakeSystemCommand }
- subject { artifact.public_send(:"#{artifact_name}_phase") }
+ subject { artifact.public_send(:"#{artifact_dsl_key}_phase", command: fake_system_command) }
context "using :launchctl" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-launchctl.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-launchctl")) }
let(:launchctl_list_cmd) { %w[/bin/launchctl list my.fancy.package.service] }
let(:launchctl_remove_cmd) { %w[/bin/launchctl remove my.fancy.package.service] }
let(:unknown_response) { "launchctl list returned unknown response\n" }
@@ -61,7 +61,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
context "using :pkgutil" do
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-pkgutil.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-pkgutil")) }
let(:main_pkg_id) { "my.fancy.package.main" }
let(:agent_pkg_id) { "my.fancy.package.agent" }
@@ -85,7 +85,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
context "using :kext" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-kext.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-kext")) }
let(:kext_id) { "my.fancy.package.kernelextension" }
it "is supported" do
@@ -110,7 +110,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
context "using :quit" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-quit.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-quit")) }
let(:bundle_id) { "my.fancy.package.app" }
let(:quit_application_script) do
%Q(tell application id "#{bundle_id}" to quit)
@@ -130,7 +130,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
context "using :signal" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-signal.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-signal")) }
let(:bundle_id) { "my.fancy.package.app" }
let(:signals) { %w[TERM KILL] }
let(:unix_pids) { [12_345, 67_890] }
@@ -149,6 +149,8 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
[:delete, :trash].each do |directive|
+ next if directive == :trash && ENV["HOMEBREW_TESTS_COVERAGE"].nil?
+
context "using :#{directive}" do
let(:dir) { TEST_TMPDIR }
let(:absolute_path) { Pathname.new("#{dir}/absolute_path") }
@@ -170,10 +172,10 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
let(:fake_system_command) { Hbc::NeverSudoSystemCommand }
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-#{directive}.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-#{directive}")) }
before(:each) do
- allow_any_instance_of(Hbc::Artifact::UninstallBase).to receive(:trash_paths)
+ allow_any_instance_of(Hbc::Artifact::AbstractUninstall).to receive(:trash_paths)
.and_wrap_original do |method, *args|
result = method.call(*args)
FileUtils.rm_rf result.stdout.split("\0")
@@ -196,7 +198,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
context "using :rmdir" do
let(:fake_system_command) { Hbc::NeverSudoSystemCommand }
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-rmdir.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-rmdir")) }
let(:empty_directory) { Pathname.new("#{TEST_TMPDIR}/empty_directory_path") }
let(:ds_store) { empty_directory.join(".DS_Store") }
@@ -223,8 +225,8 @@ shared_examples "#uninstall_phase or #zap_phase" do
[:script, :early_script].each do |script_type|
context "using #{script_type.inspect}" do
let(:fake_system_command) { Hbc::NeverSudoSystemCommand }
- let(:token) { "with-#{artifact_name}-#{script_type}".tr("_", "-") }
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/#{token}.rb") }
+ let(:token) { "with-#{artifact_dsl_key}-#{script_type}".tr("_", "-") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path(token.to_s)) }
let(:script_pathname) { cask.staged_path.join("MyFancyPkg", "FancyUninstaller.tool") }
it "is supported" do
@@ -250,7 +252,7 @@ shared_examples "#uninstall_phase or #zap_phase" do
end
context "using :login_item" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-#{artifact_name}-login-item.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-login-item")) }
it "is supported" do
Hbc::FakeSystemCommand.expects_command(
diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb
index ddc773e3e..7e140acb2 100644
--- a/Library/Homebrew/test/cask/audit_spec.rb
+++ b/Library/Homebrew/test/cask/audit_spec.rb
@@ -265,19 +265,14 @@ describe Hbc::Audit, :cask do
end
describe "generic artifact checks" do
- context "with no target" do
- let(:cask_token) { "generic-artifact-no-target" }
- it { is_expected.to fail_with(/target required for generic artifact/) }
- end
-
context "with relative target" do
let(:cask_token) { "generic-artifact-relative-target" }
- it { is_expected.to fail_with(/target must be absolute path for generic artifact/) }
+ it { is_expected.to fail_with(/target must be absolute path for Generic Artifact/) }
end
context "with absolute target" do
let(:cask_token) { "generic-artifact-absolute-target" }
- it { should_not fail_with(/target required for generic artifact/) }
+ it { should_not fail_with(/target required for Generic Artifact/) }
end
end
diff --git a/Library/Homebrew/test/cask/cask_loader/from_content_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader/from_content_loader_spec.rb
new file mode 100644
index 000000000..e735d5eca
--- /dev/null
+++ b/Library/Homebrew/test/cask/cask_loader/from_content_loader_spec.rb
@@ -0,0 +1,57 @@
+describe Hbc::CaskLoader::FromContentLoader do
+ alias_matcher :be_able_to_load, :be_can_load
+
+ describe "::can_load?" do
+ it "returns true for Casks specified with `cask \"token\" do … end`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask "token" do
+ end
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask \"token\" do; end`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask "token" do; end
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask 'token' do … end`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask 'token' do
+ end
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask 'token' do; end`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask 'token' do; end
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask(\"token\") { … }`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask("token") {
+ }
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask(\"token\") {}`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask("token") {}
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask('token') { … }`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask('token') {
+ }
+ EOS
+ end
+
+ it "returns true for Casks specified with `cask('token') {}`" do
+ expect(described_class).to be_able_to_load <<~EOS
+ cask('token') {}
+ EOS
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cask_loader/from_uri_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader/from_uri_loader_spec.rb
new file mode 100644
index 000000000..df2de1f82
--- /dev/null
+++ b/Library/Homebrew/test/cask/cask_loader/from_uri_loader_spec.rb
@@ -0,0 +1,21 @@
+describe Hbc::CaskLoader::FromURILoader do
+ alias_matcher :be_able_to_load, :be_can_load
+
+ describe "::can_load?" do
+ it "returns true when given an URI" do
+ expect(described_class).to be_able_to_load(URI("http://example.com/"))
+ end
+
+ it "returns true when given a String which can be parsed to a URI" do
+ expect(described_class).to be_able_to_load("http://example.com/")
+ end
+
+ it "returns false when given a String with Cask contents containing a URL" do
+ expect(described_class).not_to be_able_to_load <<~EOS
+ cask 'token' do
+ url 'http://example.com/'
+ end
+ EOS
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb
index a6ecc207f..5858a7c6d 100644
--- a/Library/Homebrew/test/cask/cask_spec.rb
+++ b/Library/Homebrew/test/cask/cask_spec.rb
@@ -171,4 +171,38 @@ describe Hbc::Cask, :cask do
end
end
end
+
+ describe "full_name" do
+ context "when it is a core cask" do
+ it "is the cask token" do
+ c = Hbc::CaskLoader.load("local-caffeine")
+ expect(c.full_name).to eq("local-caffeine")
+ end
+ end
+
+ context "when it is from a non-core tap" do
+ it "returns the fully-qualified name of the cask" do
+ c = Hbc::CaskLoader.load("third-party/tap/third-party-cask")
+ expect(c.full_name).to eq("third-party/tap/third-party-cask")
+ end
+ end
+
+ context "when it is from no known tap" do
+ it "retuns the cask token" do
+ file = Tempfile.new(%w[tapless-cask .rb])
+
+ begin
+ cask_name = File.basename(file.path, ".rb")
+ file.write "cask '#{cask_name}'"
+ file.close
+
+ c = Hbc::CaskLoader.load(file.path)
+ expect(c.full_name).to eq(cask_name)
+ ensure
+ file.close
+ file.unlink
+ end
+ end
+ end
+ end
end
diff --git a/Library/Homebrew/test/cask/cli/audit_spec.rb b/Library/Homebrew/test/cask/cli/audit_spec.rb
index 01f506c8c..da8bf1273 100644
--- a/Library/Homebrew/test/cask/cli/audit_spec.rb
+++ b/Library/Homebrew/test/cask/cli/audit_spec.rb
@@ -1,13 +1,19 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Audit, :cask do
- let(:cask) { double("cask", token: nil) }
+ let(:cask) { Hbc::Cask.new(nil) }
+
+ it_behaves_like "a command that handles invalid options"
describe "selection of Casks to audit" do
it "audits all Casks if no tokens are given" do
+ expect(cask).to be_a Hbc::Cask
+
allow(Hbc).to receive(:all).and_return([cask, cask])
expect(Hbc::Auditor).to receive(:audit).twice.and_return(true)
- Hbc::CLI::Audit.run
+ described_class.run
end
it "audits specified Casks if tokens are given" do
@@ -18,7 +24,7 @@ describe Hbc::CLI::Audit, :cask do
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
- Hbc::CLI::Audit.run(cask_token)
+ described_class.run(cask_token)
end
end
@@ -29,7 +35,7 @@ describe Hbc::CLI::Audit, :cask do
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
- Hbc::CLI::Audit.run("casktoken")
+ described_class.run("casktoken")
end
it "download a Cask if --download flag is set" do
@@ -38,7 +44,7 @@ describe Hbc::CLI::Audit, :cask do
.with(cask, audit_download: true, check_token_conflicts: false)
.and_return(true)
- Hbc::CLI::Audit.run("casktoken", "--download")
+ described_class.run("casktoken", "--download")
end
end
@@ -49,7 +55,7 @@ describe Hbc::CLI::Audit, :cask do
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
- Hbc::CLI::Audit.run("casktoken")
+ described_class.run("casktoken")
end
it "checks for token conflicts if --token-conflicts flag is set" do
@@ -58,7 +64,7 @@ describe Hbc::CLI::Audit, :cask do
.with(cask, audit_download: false, check_token_conflicts: true)
.and_return(true)
- Hbc::CLI::Audit.run("casktoken", "--token-conflicts")
+ described_class.run("casktoken", "--token-conflicts")
end
end
end
diff --git a/Library/Homebrew/test/cask/cli/cat_spec.rb b/Library/Homebrew/test/cask/cli/cat_spec.rb
index b726a0b36..6b54a2e4b 100644
--- a/Library/Homebrew/test/cask/cli/cat_spec.rb
+++ b/Library/Homebrew/test/cask/cli/cat_spec.rb
@@ -1,4 +1,10 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Cat, :cask do
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
describe "given a basic Cask" do
let(:basic_cask_content) {
<<-EOS.undent
@@ -16,42 +22,19 @@ describe Hbc::CLI::Cat, :cask do
it "displays the Cask file content about the specified Cask" do
expect {
- Hbc::CLI::Cat.run("basic-cask")
+ described_class.run("basic-cask")
}.to output(basic_cask_content).to_stdout
end
it "can display multiple Casks" do
expect {
- Hbc::CLI::Cat.run("basic-cask", "basic-cask")
+ described_class.run("basic-cask", "basic-cask")
}.to output(basic_cask_content * 2).to_stdout
end
-
- it "fails when option is unknown" do
- expect {
- Hbc::CLI::Cat.run("--notavalidoption", "basic-cask")
- }.to raise_error(/invalid option/)
- end
end
it "raises an exception when the Cask does not exist" do
- expect { Hbc::CLI::Cat.run("notacask") }
- .to output(/is unavailable/).to_stderr
- .and raise_error(Hbc::CaskError, "Cat incomplete.")
- end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Cat.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Cat.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
+ expect { described_class.run("notacask") }
+ .to raise_error(Hbc::CaskUnavailableError, /is unavailable/)
end
end
diff --git a/Library/Homebrew/test/cask/cli/cleanup_spec.rb b/Library/Homebrew/test/cask/cli/cleanup_spec.rb
index 64e3ef49f..7cf00352d 100644
--- a/Library/Homebrew/test/cask/cli/cleanup_spec.rb
+++ b/Library/Homebrew/test/cask/cli/cleanup_spec.rb
@@ -1,3 +1,5 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Cleanup, :cask do
let(:cache_location) { Pathname.new(Dir.mktmpdir).realpath }
let(:outdated_only) { false }
@@ -12,6 +14,8 @@ describe Hbc::CLI::Cleanup, :cask do
cache_location.rmtree
end
+ it_behaves_like "a command that handles invalid options"
+
describe "cleanup" do
let(:cask_token) { "caffeine" }
let(:cask_tokens) { [cask_token] }
diff --git a/Library/Homebrew/test/cask/cli/create_spec.rb b/Library/Homebrew/test/cask/cli/create_spec.rb
index d77b0a2aa..60c03db75 100644
--- a/Library/Homebrew/test/cask/cli/create_spec.rb
+++ b/Library/Homebrew/test/cask/cli/create_spec.rb
@@ -1,3 +1,6 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Create, :cask do
around(:each) do |example|
begin
@@ -13,6 +16,9 @@ describe Hbc::CLI::Create, :cask do
allow_any_instance_of(described_class).to receive(:exec_editor)
end
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "opens the editor for the specified Cask" do
command = described_class.new("new-cask")
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("new-cask"))
@@ -39,7 +45,7 @@ describe Hbc::CLI::Create, :cask do
it "raises an exception when more than one Cask is given" do
expect {
described_class.run("additional-cask", "another-cask")
- }.to raise_error(/Only one Cask can be created at a time./)
+ }.to raise_error(/Only one Cask can be created at a time\./)
end
it "raises an exception when the Cask already exists" do
@@ -53,26 +59,4 @@ describe Hbc::CLI::Create, :cask do
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("local-caff"))
command.run
end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- described_class.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- context "when an invalid option is specified" do
- it "raises an exception when no Cask is specified" do
- expect {
- described_class.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
-
- it "raises an exception" do
- expect {
- described_class.run("--notavalidoption", "yet-another-cask")
- }.to raise_error(/invalid option/)
- end
- end
end
diff --git a/Library/Homebrew/test/cask/cli/doctor_spec.rb b/Library/Homebrew/test/cask/cli/doctor_spec.rb
index b24c777eb..e3967060e 100644
--- a/Library/Homebrew/test/cask/cli/doctor_spec.rb
+++ b/Library/Homebrew/test/cask/cli/doctor_spec.rb
@@ -1,4 +1,8 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Doctor, :cask do
+ it_behaves_like "a command that handles invalid options"
+
it "displays some nice info about the environment" do
expect {
Hbc::CLI::Doctor.run
diff --git a/Library/Homebrew/test/cask/cli/edit_spec.rb b/Library/Homebrew/test/cask/cli/edit_spec.rb
index 5d5cbf4b9..347522020 100644
--- a/Library/Homebrew/test/cask/cli/edit_spec.rb
+++ b/Library/Homebrew/test/cask/cli/edit_spec.rb
@@ -1,8 +1,14 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Edit, :cask do
before(:each) do
allow_any_instance_of(described_class).to receive(:exec_editor)
end
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "opens the editor for the specified Cask" do
command = described_class.new("local-caffeine")
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("local-caffeine"))
@@ -12,7 +18,7 @@ describe Hbc::CLI::Edit, :cask do
it "raises an error when given more than one argument" do
expect {
described_class.new("local-caffeine", "local-transmission")
- }.to raise_error(/Only one Cask can be created at a time./)
+ }.to raise_error(/Only one Cask can be edited at a time\./)
end
it "raises an exception when the Cask doesnt exist" do
@@ -20,20 +26,4 @@ describe Hbc::CLI::Edit, :cask do
described_class.run("notacask")
}.to raise_error(Hbc::CaskUnavailableError)
end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- described_class.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- described_class.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
- end
end
diff --git a/Library/Homebrew/test/cask/cli/fetch_spec.rb b/Library/Homebrew/test/cask/cli/fetch_spec.rb
index f71c23fb6..67cf6e61d 100644
--- a/Library/Homebrew/test/cask/cli/fetch_spec.rb
+++ b/Library/Homebrew/test/cask/cli/fetch_spec.rb
@@ -1,14 +1,20 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Fetch, :cask do
let(:local_transmission) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ Hbc::CaskLoader.load(cask_path("local-transmission"))
}
let(:local_caffeine) {
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ Hbc::CaskLoader.load(cask_path("local-caffeine"))
}
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "allows download the installer of a Cask" do
- Hbc::CLI::Fetch.run("local-transmission", "local-caffeine")
+ described_class.run("local-transmission", "local-caffeine")
expect(Hbc::CurlDownloadStrategy.new(local_transmission).cached_location).to exist
expect(Hbc::CurlDownloadStrategy.new(local_caffeine).cached_location).to exist
end
@@ -19,7 +25,7 @@ describe Hbc::CLI::Fetch, :cask do
Hbc::Download.new(local_transmission).perform
old_ctime = File.stat(download_stategy.cached_location).ctime
- Hbc::CLI::Fetch.run("local-transmission")
+ described_class.run("local-transmission")
new_ctime = File.stat(download_stategy.cached_location).ctime
expect(old_ctime.to_i).to eq(new_ctime.to_i)
@@ -32,7 +38,7 @@ describe Hbc::CLI::Fetch, :cask do
old_ctime = File.stat(download_stategy.cached_location).ctime
sleep(1)
- Hbc::CLI::Fetch.run("local-transmission", "--force")
+ described_class.run("local-transmission", "--force")
download_stategy = Hbc::CurlDownloadStrategy.new(local_transmission)
new_ctime = File.stat(download_stategy.cached_location).ctime
@@ -41,23 +47,7 @@ describe Hbc::CLI::Fetch, :cask do
it "properly handles Casks that are not present" do
expect {
- Hbc::CLI::Fetch.run("notacask")
- }.to raise_error(Hbc::CaskError, "Fetch incomplete.")
- end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Fetch.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Fetch.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
+ described_class.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
end
end
diff --git a/Library/Homebrew/test/cask/cli/home_spec.rb b/Library/Homebrew/test/cask/cli/home_spec.rb
index e985fb6cd..8960d2acc 100644
--- a/Library/Homebrew/test/cask/cli/home_spec.rb
+++ b/Library/Homebrew/test/cask/cli/home_spec.rb
@@ -1,8 +1,12 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Home, :cask do
before do
allow(described_class).to receive(:open_url)
end
+ it_behaves_like "a command that handles invalid options"
+
it "opens the homepage for the specified Cask" do
expect(described_class).to receive(:open_url).with("http://example.com/local-caffeine")
described_class.run("local-caffeine")
diff --git a/Library/Homebrew/test/cask/cli/info_spec.rb b/Library/Homebrew/test/cask/cli/info_spec.rb
index bffe900ec..e24eead11 100644
--- a/Library/Homebrew/test/cask/cli/info_spec.rb
+++ b/Library/Homebrew/test/cask/cli/info_spec.rb
@@ -1,7 +1,13 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Info, :cask do
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "displays some nice info about the specified Cask" do
expect {
- Hbc::CLI::Info.run("local-caffeine")
+ described_class.run("local-caffeine")
}.to output(<<-EOS.undent).to_stdout
local-caffeine: 1.2.3
http://example.com/local-caffeine
@@ -10,7 +16,7 @@ describe Hbc::CLI::Info, :cask do
==> Name
None
==> Artifacts
- Caffeine.app (app)
+ Caffeine.app (App)
EOS
end
@@ -24,7 +30,7 @@ describe Hbc::CLI::Info, :cask do
==> Name
None
==> Artifacts
- Caffeine.app (app)
+ Caffeine.app (App)
local-transmission: 2.61
http://example.com/local-transmission
Not installed
@@ -32,26 +38,20 @@ describe Hbc::CLI::Info, :cask do
==> Name
None
==> Artifacts
- Transmission.app (app)
+ Transmission.app (App)
EOS
}
it "displays the info" do
expect {
- Hbc::CLI::Info.run("local-caffeine", "local-transmission")
+ described_class.run("local-caffeine", "local-transmission")
}.to output(expected_output).to_stdout
end
-
- it "throws away stray options" do
- expect {
- Hbc::CLI::Info.run("--notavalidoption", "local-caffeine", "local-transmission")
- }.to raise_error(/invalid option/)
- end
end
it "should print caveats if the Cask provided one" do
expect {
- Hbc::CLI::Info.run("with-caveats")
+ described_class.run("with-caveats")
}.to output(<<-EOS.undent).to_stdout
with-caveats: 1.2.3
http://example.com/local-caffeine
@@ -60,7 +60,7 @@ describe Hbc::CLI::Info, :cask do
==> Name
None
==> Artifacts
- Caffeine.app (app)
+ Caffeine.app (App)
==> Caveats
Here are some things you might want to know.
@@ -77,7 +77,7 @@ describe Hbc::CLI::Info, :cask do
it 'should not print "Caveats" section divider if the caveats block has no output' do
expect {
- Hbc::CLI::Info.run("with-conditional-caveats")
+ described_class.run("with-conditional-caveats")
}.to output(<<-EOS.undent).to_stdout
with-conditional-caveats: 1.2.3
http://example.com/local-caffeine
@@ -86,23 +86,39 @@ describe Hbc::CLI::Info, :cask do
==> Name
None
==> Artifacts
- Caffeine.app (app)
+ Caffeine.app (App)
EOS
end
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Info.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
+ it "prints languages specified in the Cask" do
+ expect {
+ described_class.run("with-languages")
+ }.to output(<<-EOS.undent).to_stdout
+ with-languages: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/with-languages.rb
+ ==> Name
+ None
+ ==> Languages
+ zh, en-US
+ ==> Artifacts
+ Caffeine.app (App)
+ EOS
end
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Info.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
+ it 'does not print "Languages" section divider if the languages block has no output' do
+ expect {
+ described_class.run("without-languages")
+ }.to output(<<-EOS.undent).to_stdout
+ without-languages: 1.2.3
+ http://example.com/local-caffeine
+ Not installed
+ From: https://github.com/caskroom/homebrew-spec/blob/master/Casks/without-languages.rb
+ ==> Name
+ None
+ ==> Artifacts
+ Caffeine.app (App)
+ EOS
end
end
diff --git a/Library/Homebrew/test/cask/cli/install_spec.rb b/Library/Homebrew/test/cask/cli/install_spec.rb
index 64feacce9..c918a3529 100644
--- a/Library/Homebrew/test/cask/cli/install_spec.rb
+++ b/Library/Homebrew/test/cask/cli/install_spec.rb
@@ -1,4 +1,10 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Install, :cask do
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "displays the installation progress" do
output = Regexp.new <<-EOS.undent
==> Downloading file:.*caffeine.zip
@@ -9,103 +15,65 @@ describe Hbc::CLI::Install, :cask do
EOS
expect {
- Hbc::CLI::Install.run("local-caffeine")
+ described_class.run("local-caffeine")
}.to output(output).to_stdout
end
it "allows staging and activation of multiple Casks at once" do
- Hbc::CLI::Install.run("local-transmission", "local-caffeine")
+ described_class.run("local-transmission", "local-caffeine")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed
expect(Hbc.appdir.join("Transmission.app")).to be_a_directory
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-caffeine"))).to be_installed
expect(Hbc.appdir.join("Caffeine.app")).to be_a_directory
end
it "skips double install (without nuking existing installation)" do
- Hbc::CLI::Install.run("local-transmission")
- Hbc::CLI::Install.run("local-transmission")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ described_class.run("local-transmission")
+ described_class.run("local-transmission")
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed
end
it "prints a warning message on double install" do
- Hbc::CLI::Install.run("local-transmission")
+ described_class.run("local-transmission")
expect {
- Hbc::CLI::Install.run("local-transmission")
+ described_class.run("local-transmission")
}.to output(/Warning: Cask 'local-transmission' is already installed./).to_stderr
end
it "allows double install with --force" do
- Hbc::CLI::Install.run("local-transmission")
+ described_class.run("local-transmission")
expect {
expect {
- Hbc::CLI::Install.run("local-transmission", "--force")
+ described_class.run("local-transmission", "--force")
}.to output(/It seems there is already an App at.*overwriting\./).to_stderr
}.to output(/local-transmission was successfully installed!/).to_stdout
end
it "skips dependencies with --skip-cask-deps" do
- Hbc::CLI::Install.run("with-depends-on-cask-multiple", "--skip-cask-deps")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-cask-multiple.rb")).to be_installed
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")).not_to be_installed
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).not_to be_installed
+ described_class.run("with-depends-on-cask-multiple", "--skip-cask-deps")
+ expect(Hbc::CaskLoader.load(cask_path("with-depends-on-cask-multiple"))).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-caffeine"))).not_to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).not_to be_installed
end
it "properly handles Casks that are not present" do
expect {
- Hbc::CLI::Install.run("notacask")
- }.to raise_error(Hbc::CaskError, "Install incomplete.")
+ described_class.run("notacask")
+ }.to raise_error(Hbc::CaskUnavailableError)
end
it "returns a suggestion for a misspelled Cask" do
expect {
- begin
- Hbc::CLI::Install.run("localcaffeine")
- rescue Hbc::CaskError
- nil
- end
- }.to output(/Cask 'localcaffeine' is unavailable: No Cask with this name exists\. Did you mean:\nlocal-caffeine/).to_stderr
+ described_class.run("localcaffeine")
+ }.to raise_error(Hbc::CaskUnavailableError, /Cask 'localcaffeine' is unavailable: No Cask with this name exists\. Did you mean “local-caffeine”?/)
end
it "returns multiple suggestions for a Cask fragment" do
expect {
- begin
- Hbc::CLI::Install.run("local-caf")
- rescue Hbc::CaskError
- nil
- end
- }.to output(/Cask 'local-caf' is unavailable: No Cask with this name exists\. Did you mean one of:\nlocal-caffeine/).to_stderr
- end
-
- describe "when no Cask is specified" do
- with_options = lambda do |options|
- it "raises an exception" do
- expect {
- Hbc::CLI::Install.run(*options)
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "without options" do
- with_options.call([])
- end
-
- describe "with --force" do
- with_options.call(["--force"])
- end
-
- describe "with --skip-cask-deps" do
- with_options.call(["--skip-cask-deps"])
- end
-
- describe "with an invalid option" do
- it "raises an error" do
- expect {
- Hbc::CLI::Install.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
- end
+ described_class.run("local")
+ }.to raise_error(Hbc::CaskUnavailableError, /Cask 'local' is unavailable: No Cask with this name exists\. Did you mean one of these\?\nlocal-caffeine\nlocal-transmission/)
end
end
diff --git a/Library/Homebrew/test/cask/cli/list_spec.rb b/Library/Homebrew/test/cask/cli/list_spec.rb
index ecca3035f..301ca9b89 100644
--- a/Library/Homebrew/test/cask/cli/list_spec.rb
+++ b/Library/Homebrew/test/cask/cli/list_spec.rb
@@ -1,4 +1,8 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::List, :cask do
+ it_behaves_like "a command that handles invalid options"
+
it "lists the installed Casks in a pretty fashion" do
casks = %w[local-caffeine local-transmission].map { |c| Hbc::CaskLoader.load(c) }
@@ -7,10 +11,30 @@ describe Hbc::CLI::List, :cask do
end
expect {
- Hbc::CLI::List.run
+ described_class.run
+ }.to output(<<-EOS.undent).to_stdout
+ local-caffeine
+ local-transmission
+ EOS
+ end
+
+ it "lists full names" do
+ casks = %w[
+ local-caffeine
+ third-party/tap/third-party-cask
+ local-transmission
+ ].map { |c| Hbc::CaskLoader.load(c) }
+
+ casks.each do |c|
+ InstallHelper.install_with_caskfile(c)
+ end
+
+ expect {
+ described_class.run("--full-name")
}.to output(<<-EOS.undent).to_stdout
local-caffeine
local-transmission
+ third-party/tap/third-party-cask
EOS
end
@@ -29,29 +53,31 @@ describe Hbc::CLI::List, :cask do
it "of all installed Casks" do
expect {
- Hbc::CLI::List.run("--versions")
+ described_class.run("--versions")
}.to output(expected_output).to_stdout
end
it "of given Casks" do
expect {
- Hbc::CLI::List.run("--versions", "local-caffeine", "local-transmission")
+ described_class.run("--versions", "local-caffeine", "local-transmission")
}.to output(expected_output).to_stdout
end
end
describe "given a set of installed Casks" do
- let(:caffeine) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") }
- let(:transmission) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb") }
+ let(:caffeine) { Hbc::CaskLoader.load(cask_path("local-caffeine")) }
+ let(:transmission) { Hbc::CaskLoader.load(cask_path("local-transmission")) }
let(:casks) { [caffeine, transmission] }
it "lists the installed files for those Casks" do
casks.each(&InstallHelper.method(:install_without_artifacts_with_caskfile))
- Hbc::Artifact::App.new(transmission).install_phase
+ transmission.artifacts.select { |a| a.is_a?(Hbc::Artifact::App) }.each do |artifact|
+ artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false)
+ end
expect {
- Hbc::CLI::List.run("local-transmission", "local-caffeine")
+ described_class.run("local-transmission", "local-caffeine")
}.to output(<<-EOS.undent).to_stdout
==> Apps
#{Hbc.appdir.join("Transmission.app")} (#{Hbc.appdir.join("Transmission.app").abv})
diff --git a/Library/Homebrew/test/cask/cli/options_spec.rb b/Library/Homebrew/test/cask/cli/options_spec.rb
index 98eb05f7e..82d830795 100644
--- a/Library/Homebrew/test/cask/cli/options_spec.rb
+++ b/Library/Homebrew/test/cask/cli/options_spec.rb
@@ -1,6 +1,6 @@
describe Hbc::CLI, :cask do
it "supports setting the appdir" do
- Hbc::CLI.new.process_options("help", "--appdir=/some/path/foo")
+ described_class.new.process_options("help", "--appdir=/some/path/foo")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/foo"))
end
@@ -8,13 +8,13 @@ describe Hbc::CLI, :cask do
it "supports setting the appdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--appdir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the prefpanedir" do
- Hbc::CLI.new.process_options("help", "--prefpanedir=/some/path/foo")
+ described_class.new.process_options("help", "--prefpanedir=/some/path/foo")
expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/foo"))
end
@@ -22,13 +22,13 @@ describe Hbc::CLI, :cask do
it "supports setting the prefpanedir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--prefpanedir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the qlplugindir" do
- Hbc::CLI.new.process_options("help", "--qlplugindir=/some/path/foo")
+ described_class.new.process_options("help", "--qlplugindir=/some/path/foo")
expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/foo"))
end
@@ -36,13 +36,13 @@ describe Hbc::CLI, :cask do
it "supports setting the qlplugindir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--qlplugindir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the colorpickerdir" do
- Hbc::CLI.new.process_options("help", "--colorpickerdir=/some/path/foo")
+ described_class.new.process_options("help", "--colorpickerdir=/some/path/foo")
expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/foo"))
end
@@ -50,13 +50,13 @@ describe Hbc::CLI, :cask do
it "supports setting the colorpickerdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--colorpickerdir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the dictionarydir" do
- Hbc::CLI.new.process_options("help", "--dictionarydir=/some/path/foo")
+ described_class.new.process_options("help", "--dictionarydir=/some/path/foo")
expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/foo"))
end
@@ -64,13 +64,13 @@ describe Hbc::CLI, :cask do
it "supports setting the dictionarydir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--dictionarydir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the fontdir" do
- Hbc::CLI.new.process_options("help", "--fontdir=/some/path/foo")
+ described_class.new.process_options("help", "--fontdir=/some/path/foo")
expect(Hbc.fontdir).to eq(Pathname.new("/some/path/foo"))
end
@@ -78,13 +78,13 @@ describe Hbc::CLI, :cask do
it "supports setting the fontdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--fontdir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.fontdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the servicedir" do
- Hbc::CLI.new.process_options("help", "--servicedir=/some/path/foo")
+ described_class.new.process_options("help", "--servicedir=/some/path/foo")
expect(Hbc.servicedir).to eq(Pathname.new("/some/path/foo"))
end
@@ -92,13 +92,13 @@ describe Hbc::CLI, :cask do
it "supports setting the servicedir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--servicedir=/some/path/bar"
- Hbc::CLI.new.process_options("help")
+ described_class.new.process_options("help")
expect(Hbc.servicedir).to eq(Pathname.new("/some/path/bar"))
end
it "allows additional options to be passed through" do
- rest = Hbc::CLI.new.process_options("edit", "foo", "--create", "--appdir=/some/path/qux")
+ rest = described_class.new.process_options("edit", "foo", "--create", "--appdir=/some/path/qux")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/qux"))
expect(rest).to eq(%w[edit foo --create])
@@ -106,7 +106,7 @@ describe Hbc::CLI, :cask do
describe "--help" do
it "sets the Cask help method to true" do
- command = Hbc::CLI.new("foo", "--help")
+ command = described_class.new("foo", "--help")
expect(command.help?).to be true
end
end
diff --git a/Library/Homebrew/test/cask/cli/outdated_spec.rb b/Library/Homebrew/test/cask/cli/outdated_spec.rb
index 946092f89..5bbf18d21 100644
--- a/Library/Homebrew/test/cask/cli/outdated_spec.rb
+++ b/Library/Homebrew/test/cask/cli/outdated_spec.rb
@@ -1,11 +1,13 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Outdated, :cask do
let(:installed) do
[
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb"),
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/outdated/local-caffeine.rb"),
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/outdated/local-transmission.rb"),
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/version-latest-string.rb"),
- Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/outdated/auto-updates.rb"),
+ Hbc::CaskLoader.load(cask_path("basic-cask")),
+ Hbc::CaskLoader.load(cask_path("outdated/local-caffeine")),
+ Hbc::CaskLoader.load(cask_path("outdated/local-transmission")),
+ Hbc::CaskLoader.load(cask_path("version-latest-string")),
+ Hbc::CaskLoader.load(cask_path("outdated/auto-updates")),
]
end
@@ -15,6 +17,8 @@ describe Hbc::CLI::Outdated, :cask do
allow_any_instance_of(described_class).to receive(:verbose?).and_return(true)
end
+ it_behaves_like "a command that handles invalid options"
+
describe 'without --greedy it ignores the Casks with "vesion latest" or "auto_updates true"' do
it "checks all the installed Casks when no token is provided" do
expect {
@@ -70,7 +74,7 @@ describe Hbc::CLI::Outdated, :cask do
end
it 'does not include the Casks with "auto_updates true" when the version did not change' do
- cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/auto-updates.rb")
+ cask = Hbc::CaskLoader.load(cask_path("auto-updates"))
InstallHelper.install_with_caskfile(cask)
expect {
diff --git a/Library/Homebrew/test/cask/cli/reinstall_spec.rb b/Library/Homebrew/test/cask/cli/reinstall_spec.rb
index 3a9c3e2f5..95294b695 100644
--- a/Library/Homebrew/test/cask/cli/reinstall_spec.rb
+++ b/Library/Homebrew/test/cask/cli/reinstall_spec.rb
@@ -1,6 +1,10 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Reinstall, :cask do
+ it_behaves_like "a command that handles invalid options"
+
it "displays the reinstallation progress" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
Hbc::Installer.new(caffeine).install
@@ -23,16 +27,16 @@ describe Hbc::CLI::Reinstall, :cask do
it "allows reinstalling a Cask" do
Hbc::CLI::Install.run("local-transmission")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed
Hbc::CLI::Reinstall.run("local-transmission")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed
end
it "allows reinstalling a non installed Cask" do
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).not_to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).not_to be_installed
Hbc::CLI::Reinstall.run("local-transmission")
- expect(Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")).to be_installed
+ expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed
end
end
diff --git a/Library/Homebrew/test/cask/cli/search_spec.rb b/Library/Homebrew/test/cask/cli/search_spec.rb
index e237ad464..a4f796f3c 100644
--- a/Library/Homebrew/test/cask/cli/search_spec.rb
+++ b/Library/Homebrew/test/cask/cli/search_spec.rb
@@ -1,9 +1,15 @@
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Search, :cask do
before(:each) do
allow(Tty).to receive(:width).and_return(0)
end
+ it_behaves_like "a command that handles invalid options"
+
it "lists the available Casks that match the search term" do
+ allow(GitHub).to receive(:search_code).and_return([])
+
expect {
Hbc::CLI::Search.run("local")
}.to output(<<-EOS.undent).to_stdout.as_tty
@@ -14,24 +20,47 @@ describe Hbc::CLI::Search, :cask do
end
it "outputs a plain list when stdout is not a TTY" do
+ allow(GitHub).to receive(:search_code).and_return([])
+
+ expect {
+ Hbc::CLI::Search.run("local")
+ }.to output(<<-EOS.undent).to_stdout
+ local-caffeine
+ local-transmission
+ EOS
+ end
+
+ it "returns matches even when online search failed" do
+ allow(GitHub).to receive(:search_code).and_raise(GitHub::Error.new("reason"))
+
expect {
Hbc::CLI::Search.run("local")
}.to output(<<-EOS.undent).to_stdout
local-caffeine
local-transmission
EOS
+ .and output(/^Warning: Error searching on GitHub: reason/).to_stderr
end
it "shows that there are no Casks matching a search term that did not result in anything" do
expect {
Hbc::CLI::Search.run("foo-bar-baz")
- }.to output("No Cask found for \"foo-bar-baz\".\n").to_stdout.as_tty
+ }.to output(<<-EOS.undent).to_stdout.as_tty
+ No Cask found for "foo-bar-baz".
+ EOS
end
- it "lists all available Casks with no search term" do
- expect {
- Hbc::CLI::Search.run
- }.to output(/local-caffeine/).to_stdout.as_tty
+ it "doesn't output anything to non-TTY stdout when there are no matches" do
+ expect { Hbc::CLI::Search.run("foo-bar-baz") }
+ .to not_to_output.to_stdout
+ .and not_to_output.to_stderr
+ end
+
+ it "lists all Casks available offline with no search term" do
+ allow(GitHub).to receive(:search_code).and_raise(GitHub::Error.new("reason"))
+ expect { Hbc::CLI::Search.run }
+ .to output(/local-caffeine/).to_stdout.as_tty
+ .and not_to_output.to_stderr
end
it "ignores hyphens in search terms" do
@@ -55,19 +84,29 @@ describe Hbc::CLI::Search, :cask do
it "accepts a regexp argument" do
expect {
Hbc::CLI::Search.run("/^local-c[a-z]ffeine$/")
- }.to output("==> Regexp Matches\nlocal-caffeine\n").to_stdout.as_tty
+ }.to output(<<-EOS.undent).to_stdout.as_tty
+ ==> Regexp Matches
+ local-caffeine
+ EOS
end
- it "Returns both exact and partial matches" do
+ it "returns both exact and partial matches" do
expect {
Hbc::CLI::Search.run("test-opera")
- }.to output(/^==> Exact Match\ntest-opera\n==> Partial Matches\ntest-opera-mail/).to_stdout.as_tty
+ }.to output(<<-EOS.undent).to_stdout.as_tty
+ ==> Exact Match
+ test-opera
+ ==> Partial Matches
+ test-opera-mail
+ EOS
end
it "does not search the Tap name" do
expect {
Hbc::CLI::Search.run("caskroom")
- }.to output(/^No Cask found for "caskroom"\.\n/).to_stdout.as_tty
+ }.to output(<<-EOS.undent).to_stdout.as_tty
+ No Cask found for "caskroom".
+ EOS
end
it "doesn't highlight packages that aren't installed" do
diff --git a/Library/Homebrew/test/cask/cli/shared_examples/invalid_option.rb b/Library/Homebrew/test/cask/cli/shared_examples/invalid_option.rb
new file mode 100644
index 000000000..12a05be92
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/shared_examples/invalid_option.rb
@@ -0,0 +1,15 @@
+shared_examples "a command that handles invalid options" do
+ context "when an invalid option is specified" do
+ it "raises an exception when no Cask is specified" do
+ expect {
+ described_class.run("--not-a-valid-option")
+ }.to raise_error("invalid option: --not-a-valid-option")
+ end
+
+ it "raises an exception when a Cask is specified" do
+ expect {
+ described_class.run("--not-a-valid-option", "basic-cask")
+ }.to raise_error("invalid option: --not-a-valid-option")
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/shared_examples/requires_cask_token.rb b/Library/Homebrew/test/cask/cli/shared_examples/requires_cask_token.rb
new file mode 100644
index 000000000..dc1e471e5
--- /dev/null
+++ b/Library/Homebrew/test/cask/cli/shared_examples/requires_cask_token.rb
@@ -0,0 +1,9 @@
+shared_examples "a command that requires a Cask token" do
+ context "when no Cask is specified" do
+ it "raises an exception " do
+ expect {
+ described_class.run
+ }.to raise_error(Hbc::CaskUnspecifiedError, "This command requires a Cask token.")
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/cli/style_spec.rb b/Library/Homebrew/test/cask/cli/style_spec.rb
index 2007b87d7..12cd348a0 100644
--- a/Library/Homebrew/test/cask/cli/style_spec.rb
+++ b/Library/Homebrew/test/cask/cli/style_spec.rb
@@ -1,11 +1,13 @@
require "open3"
require "rubygems"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Style, :cask do
let(:args) { [] }
let(:cli) { described_class.new(*args) }
- around(&:run)
+ it_behaves_like "a command that handles invalid options"
describe "#run" do
subject { cli.run }
diff --git a/Library/Homebrew/test/cask/cli/uninstall_spec.rb b/Library/Homebrew/test/cask/cli/uninstall_spec.rb
index 1a1c57e88..80b7edbd3 100644
--- a/Library/Homebrew/test/cask/cli/uninstall_spec.rb
+++ b/Library/Homebrew/test/cask/cli/uninstall_spec.rb
@@ -1,6 +1,12 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Uninstall, :cask do
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "displays the uninstallation progress" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
Hbc::Installer.new(caffeine).install
@@ -10,31 +16,29 @@ describe Hbc::CLI::Uninstall, :cask do
EOS
expect {
- Hbc::CLI::Uninstall.run("local-caffeine")
+ described_class.run("local-caffeine")
}.to output(output).to_stdout
end
it "shows an error when a bad Cask is provided" do
- expect { Hbc::CLI::Uninstall.run("notacask") }
- .to output(/is unavailable/).to_stderr
- .and raise_error(Hbc::CaskError, "Uninstall incomplete.")
+ expect { described_class.run("notacask") }
+ .to raise_error(Hbc::CaskUnavailableError, /is unavailable/)
end
it "shows an error when a Cask is provided that's not installed" do
- expect { Hbc::CLI::Uninstall.run("local-caffeine") }
- .to output(/is not installed/).to_stderr
- .and raise_error(Hbc::CaskError, "Uninstall incomplete.")
+ expect { described_class.run("local-caffeine") }
+ .to raise_error(Hbc::CaskNotInstalledError, /is not installed/)
end
it "tries anyway on a non-present Cask when --force is given" do
expect {
- Hbc::CLI::Uninstall.run("local-caffeine", "--force")
+ described_class.run("local-caffeine", "--force")
}.not_to raise_error
end
it "can uninstall and unlink multiple Casks at once" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
- transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
+ transmission = Hbc::CaskLoader.load(cask_path("local-transmission"))
Hbc::Installer.new(caffeine).install
Hbc::Installer.new(transmission).install
@@ -42,7 +46,7 @@ describe Hbc::CLI::Uninstall, :cask do
expect(caffeine).to be_installed
expect(transmission).to be_installed
- Hbc::CLI::Uninstall.run("local-caffeine", "local-transmission")
+ described_class.run("local-caffeine", "local-transmission")
expect(caffeine).not_to be_installed
expect(Hbc.appdir.join("Transmission.app")).not_to exist
@@ -51,7 +55,7 @@ describe Hbc::CLI::Uninstall, :cask do
end
it "calls `uninstall` before removing artifacts" do
- cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-uninstall-script-app.rb")
+ cask = Hbc::CaskLoader.load(cask_path("with-uninstall-script-app"))
Hbc::Installer.new(cask).install
@@ -59,7 +63,7 @@ describe Hbc::CLI::Uninstall, :cask do
expect(Hbc.appdir.join("MyFancyApp.app")).to exist
expect {
- Hbc::CLI::Uninstall.run("with-uninstall-script-app")
+ described_class.run("with-uninstall-script-app")
}.not_to raise_error
expect(cask).not_to be_installed
@@ -67,7 +71,7 @@ describe Hbc::CLI::Uninstall, :cask do
end
it "can uninstall Casks when the uninstall script is missing, but only when using `--force`" do
- cask = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-uninstall-script-app.rb")
+ cask = Hbc::CaskLoader.load(cask_path("with-uninstall-script-app"))
Hbc::Installer.new(cask).install
@@ -75,14 +79,13 @@ describe Hbc::CLI::Uninstall, :cask do
Hbc.appdir.join("MyFancyApp.app").rmtree
- expect { Hbc::CLI::Uninstall.run("with-uninstall-script-app") }
- .to output(/does not exist/).to_stderr
- .and raise_error(Hbc::CaskError, "Uninstall incomplete.")
+ expect { described_class.run("with-uninstall-script-app") }
+ .to raise_error(Hbc::CaskError, /uninstall script .* does not exist/)
expect(cask).to be_installed
expect {
- Hbc::CLI::Uninstall.run("with-uninstall-script-app", "--force")
+ described_class.run("with-uninstall-script-app", "--force")
}.not_to raise_error
expect(cask).not_to be_installed
@@ -115,13 +118,13 @@ describe Hbc::CLI::Uninstall, :cask do
end
it "uninstalls one version at a time" do
- Hbc::CLI::Uninstall.run("versioned-cask")
+ described_class.run("versioned-cask")
expect(caskroom_path.join(first_installed_version)).to exist
expect(caskroom_path.join(last_installed_version)).not_to exist
expect(caskroom_path).to exist
- Hbc::CLI::Uninstall.run("versioned-cask")
+ described_class.run("versioned-cask")
expect(caskroom_path.join(first_installed_version)).not_to exist
expect(caskroom_path).not_to exist
@@ -130,7 +133,7 @@ describe Hbc::CLI::Uninstall, :cask do
it "displays a message when versions remain installed" do
expect {
expect {
- Hbc::CLI::Uninstall.run("versioned-cask")
+ described_class.run("versioned-cask")
}.not_to output.to_stderr
}.to output(/#{token} #{first_installed_version} is still installed./).to_stdout
end
@@ -160,26 +163,10 @@ describe Hbc::CLI::Uninstall, :cask do
end
it "can still uninstall those Casks" do
- Hbc::CLI::Uninstall.run("ive-been-renamed")
+ described_class.run("ive-been-renamed")
expect(app).not_to exist
expect(caskroom_path).not_to exist
end
end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Uninstall.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Uninstall.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
- end
end
diff --git a/Library/Homebrew/test/cask/cli/zap_spec.rb b/Library/Homebrew/test/cask/cli/zap_spec.rb
index fdc5b4125..05c882854 100644
--- a/Library/Homebrew/test/cask/cli/zap_spec.rb
+++ b/Library/Homebrew/test/cask/cli/zap_spec.rb
@@ -1,13 +1,18 @@
+require_relative "shared_examples/requires_cask_token"
+require_relative "shared_examples/invalid_option"
+
describe Hbc::CLI::Zap, :cask do
+ it_behaves_like "a command that requires a Cask token"
+ it_behaves_like "a command that handles invalid options"
+
it "shows an error when a bad Cask is provided" do
- expect { Hbc::CLI::Zap.run("notacask") }
- .to output(/is unavailable/).to_stderr
- .and raise_error(Hbc::CaskError, "Zap incomplete.")
+ expect { described_class.run("notacask") }
+ .to raise_error(Hbc::CaskUnavailableError, /is unavailable/)
end
it "can zap and unlink multiple Casks at once" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
- transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
+ transmission = Hbc::CaskLoader.load(cask_path("local-transmission"))
Hbc::Installer.new(caffeine).install
Hbc::Installer.new(transmission).install
@@ -15,7 +20,7 @@ describe Hbc::CLI::Zap, :cask do
expect(caffeine).to be_installed
expect(transmission).to be_installed
- Hbc::CLI::Zap.run("local-caffeine", "local-transmission")
+ described_class.run("local-caffeine", "local-transmission")
expect(caffeine).not_to be_installed
expect(Hbc.appdir.join("Caffeine.app")).not_to be_a_symlink
@@ -46,20 +51,4 @@ describe Hbc::CLI::Zap, :cask do
#
# with_zap.wont_be :installed?
# end
-
- describe "when no Cask is specified" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Zap.run
- }.to raise_error(Hbc::CaskUnspecifiedError)
- end
- end
-
- describe "when no Cask is specified, but an invalid option" do
- it "raises an exception" do
- expect {
- Hbc::CLI::Zap.run("--notavalidoption")
- }.to raise_error(/invalid option/)
- end
- end
end
diff --git a/Library/Homebrew/test/cask/conflicts_with_spec.rb b/Library/Homebrew/test/cask/conflicts_with_spec.rb
new file mode 100644
index 000000000..81c22ded6
--- /dev/null
+++ b/Library/Homebrew/test/cask/conflicts_with_spec.rb
@@ -0,0 +1,23 @@
+describe "conflicts_with", :cask do
+ describe "conflicts_with cask" do
+ let(:local_caffeine) {
+ Hbc::CaskLoader.load(cask_path("local-caffeine"))
+ }
+
+ let(:with_conflicts_with) {
+ Hbc::CaskLoader.load(cask_path("with-conflicts-with"))
+ }
+
+ it "installs the dependency of a Cask and the Cask itself" do
+ Hbc::Installer.new(local_caffeine).install
+
+ expect(local_caffeine).to be_installed
+
+ expect {
+ Hbc::Installer.new(with_conflicts_with).install
+ }.to raise_error(Hbc::CaskConflictError, "Cask 'with-conflicts-with' conflicts with 'local-caffeine'.")
+
+ expect(with_conflicts_with).not_to be_installed
+ end
+ end
+end
diff --git a/Library/Homebrew/test/cask/container/dmg_spec.rb b/Library/Homebrew/test/cask/container/dmg_spec.rb
index 4f3f57071..df99a6264 100644
--- a/Library/Homebrew/test/cask/container/dmg_spec.rb
+++ b/Library/Homebrew/test/cask/container/dmg_spec.rb
@@ -1,7 +1,7 @@
describe Hbc::Container::Dmg, :cask do
describe "#mount!" do
it "does not store nil mounts for dmgs with extra data" do
- transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ transmission = Hbc::CaskLoader.load(cask_path("local-transmission"))
dmg = Hbc::Container::Dmg.new(
transmission,
diff --git a/Library/Homebrew/test/cask/depends_on_spec.rb b/Library/Homebrew/test/cask/depends_on_spec.rb
index c603cf6e1..453a761f7 100644
--- a/Library/Homebrew/test/cask/depends_on_spec.rb
+++ b/Library/Homebrew/test/cask/depends_on_spec.rb
@@ -9,12 +9,15 @@ describe "Satisfy Dependencies and Requirements", :cask do
describe "depends_on cask" do
context "when depends_on cask is cyclic" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-cask-cyclic.rb") }
- it { is_expected.to raise_error(Hbc::CaskCyclicDependencyError) }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-cask-cyclic")) }
+ it {
+ is_expected.to raise_error(Hbc::CaskCyclicDependencyError,
+ "Cask 'with-depends-on-cask-cyclic' includes cyclic dependencies on other Casks: with-depends-on-cask-cyclic-helper")
+ }
end
context do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-cask")) }
let(:dependency) { Hbc::CaskLoader.load(cask.depends_on.cask.first) }
it "installs the dependency of a Cask and the Cask itself" do
@@ -27,34 +30,34 @@ describe "Satisfy Dependencies and Requirements", :cask do
describe "depends_on macos" do
context "given an array" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-array.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-macos-array")) }
it { is_expected.not_to raise_error }
end
- context "given a comparisson" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-comparison.rb") }
+ context "given a comparison" do
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-macos-comparison")) }
it { is_expected.not_to raise_error }
end
context "given a string" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-string.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-macos-string")) }
it { is_expected.not_to raise_error }
end
context "given a symbol" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-symbol.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-macos-symbol")) }
it { is_expected.not_to raise_error }
end
context "when not satisfied" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-failure.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-macos-failure")) }
it { is_expected.to raise_error(Hbc::CaskError) }
end
end
describe "depends_on arch" do
context "when satisfied" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-arch.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-arch")) }
it { is_expected.not_to raise_error }
end
end
@@ -65,21 +68,21 @@ describe "Satisfy Dependencies and Requirements", :cask do
end
context "when satisfied" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-x11.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-x11")) }
let(:x11_installed) { true }
it { is_expected.not_to raise_error }
end
context "when not satisfied" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-x11.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-x11")) }
let(:x11_installed) { false }
it { is_expected.to raise_error(Hbc::CaskX11DependencyError) }
end
context "when depends_on x11: false" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-x11-false.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("with-depends-on-x11-false")) }
let(:x11_installed) { false }
it { is_expected.not_to raise_error }
diff --git a/Library/Homebrew/test/cask/download_strategy_spec.rb b/Library/Homebrew/test/cask/download_strategy_spec.rb
index 222352c07..17da1e36e 100644
--- a/Library/Homebrew/test/cask/download_strategy_spec.rb
+++ b/Library/Homebrew/test/cask/download_strategy_spec.rb
@@ -26,9 +26,12 @@ describe "download strategies", :cask do
downloader.fetch
expect(downloader).to have_received(:curl).with(
+ "--location",
+ "--remote-time",
+ "--continue-at", "-",
+ "--output", kind_of(Pathname),
cask.url.to_s,
- "-C", 0,
- "-o", kind_of(Pathname)
+ user_agent: :default
)
end
@@ -36,25 +39,25 @@ describe "download strategies", :cask do
let(:url_options) { { user_agent: "Mozilla/25.0.1" } }
it "adds the appropriate curl args" do
- curl_args = []
- allow(downloader).to receive(:curl) { |*args| curl_args = args }
+ expect(downloader).to receive(:safe_system) { |*args|
+ expect(args.each_cons(2)).to include(["--user-agent", "Mozilla/25.0.1"])
+ }
downloader.fetch
-
- expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/25.0.1"])
end
end
context "with a generalized fake user agent" do
+ alias_matcher :a_string_matching, :match
+
let(:url_options) { { user_agent: :fake } }
it "adds the appropriate curl args" do
- curl_args = []
- allow(downloader).to receive(:curl) { |*args| curl_args = args }
+ expect(downloader).to receive(:safe_system) { |*args|
+ expect(args.each_cons(2).to_a).to include(["--user-agent", a_string_matching(/Mozilla.*Mac OS X 10.*AppleWebKit/)])
+ }
downloader.fetch
-
- expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io"])
end
end
@@ -138,7 +141,7 @@ describe "download strategies", :cask do
describe Hbc::SubversionDownloadStrategy do
let(:url_options) { { using: :svn } }
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
- let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, fake_system_command) }
+ let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, command: fake_system_command) }
before do
allow(fake_system_command).to receive(:run!)
end
@@ -147,7 +150,7 @@ describe "download strategies", :cask do
allow(downloader).to receive(:compress)
allow(downloader).to receive(:fetch_repo)
- expect(downloader.fetch).to equal(downloader.tarball_path)
+ expect(downloader.fetch).to equal(downloader.cached_location)
end
it "calls fetch_repo with default arguments for a simple Cask" do
@@ -237,44 +240,5 @@ describe "download strategies", :cask do
)
end
end
-
- it "runs tar to serialize svn downloads" do
- # sneaky stub to remake the directory, since homebrew code removes it
- # before tar is called
- allow(downloader).to receive(:fetch_repo) {
- downloader.cached_location.mkdir
- }
-
- downloader.fetch
-
- expect(fake_system_command).to have_received(:run!).with(
- "/usr/bin/tar",
- hash_including(args: [
- '-s/^\\.//',
- "--exclude",
- ".svn",
- "-cf",
- downloader.tarball_path,
- "--",
- ".",
- ]),
- )
- end
end
-
- # does not work yet, because (for unknown reasons), the tar command
- # returns an error code when running under the test suite
- # it 'creates a tarball matching the expected checksum' do
- # cask = Hbc::CaskLoader.load('svn-download-check-cask')
- # downloader = Hbc::SubversionDownloadStrategy.new(cask)
- # # special mocking required for tar to have something to work with
- # def downloader.fetch_repo(target, url, revision = nil, ignore_externals=false)
- # target.mkpath
- # FileUtils.touch(target.join('empty_file.txt'))
- # File.utime(1000,1000,target.join('empty_file.txt'))
- # end
- # expect(downloader.fetch).to equal(downloader.tarball_path)
- # d = Hbc::Download.new(cask)
- # d.send(:_check_sums, downloader.tarball_path, cask.sums)
- # end
end
diff --git a/Library/Homebrew/test/cask/dsl/appcast_spec.rb b/Library/Homebrew/test/cask/dsl/appcast_spec.rb
index b8903b1be..bf703eba2 100644
--- a/Library/Homebrew/test/cask/dsl/appcast_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/appcast_spec.rb
@@ -4,7 +4,7 @@ describe Hbc::DSL::Appcast do
subject { described_class.new(url, params) }
let(:url) { "http://example.com" }
- let(:uri) { Hbc::UnderscoreSupportingURI.parse(url) }
+ let(:uri) { URI(url) }
let(:params) { {} }
describe "#to_s" do
@@ -33,13 +33,18 @@ describe Hbc::DSL::Appcast do
describe "#calculate_checkpoint" do
before do
- expect(Hbc::SystemCommand).to receive(:run).with(*cmd_args).and_return(cmd_result)
+ expect(Hbc::SystemCommand).to receive(:run) do |executable, **options|
+ expect(executable).to eq "/usr/bin/curl"
+ expect(options[:args]).to include(*cmd_args)
+ expect(options[:print_stderr]).to be false
+ cmd_result
+ end
allow(cmd_result).to receive(:success?).and_return(cmd_success)
allow(cmd_result).to receive(:stdout).and_return(cmd_stdout)
end
context "when server returns a successful HTTP status" do
- let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] }
+ let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
let(:cmd_success) { true }
let(:cmd_stdout) { "hello world" }
@@ -56,7 +61,7 @@ describe Hbc::DSL::Appcast do
end
context "when server returns a non-successful HTTP status" do
- let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] }
+ let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
let(:cmd_success) { false }
let(:cmd_stdout) { "some error message from the server" }
diff --git a/Library/Homebrew/test/cask/dsl/caveats_spec.rb b/Library/Homebrew/test/cask/dsl/caveats_spec.rb
index aa662e4d0..1b82d9821 100644
--- a/Library/Homebrew/test/cask/dsl/caveats_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/caveats_spec.rb
@@ -1,7 +1,7 @@
require "test/support/helper/spec/shared_examples/hbc_dsl_base"
describe Hbc::DSL::Caveats, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("basic-cask")) }
let(:dsl) { Hbc::DSL::Caveats.new(cask) }
it_behaves_like Hbc::DSL::Base
diff --git a/Library/Homebrew/test/cask/dsl/postflight_spec.rb b/Library/Homebrew/test/cask/dsl/postflight_spec.rb
index d2b080ca3..4ac3ae7cf 100644
--- a/Library/Homebrew/test/cask/dsl/postflight_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/postflight_spec.rb
@@ -2,7 +2,7 @@ require "test/support/helper/spec/shared_examples/hbc_dsl_base"
require "test/support/helper/spec/shared_examples/hbc_staged"
describe Hbc::DSL::Postflight, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("basic-cask")) }
let(:dsl) { Hbc::DSL::Postflight.new(cask, Hbc::FakeSystemCommand) }
it_behaves_like Hbc::DSL::Base
diff --git a/Library/Homebrew/test/cask/dsl/preflight_spec.rb b/Library/Homebrew/test/cask/dsl/preflight_spec.rb
index b93be95ff..f78944c50 100644
--- a/Library/Homebrew/test/cask/dsl/preflight_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/preflight_spec.rb
@@ -2,7 +2,7 @@ require "test/support/helper/spec/shared_examples/hbc_dsl_base"
require "test/support/helper/spec/shared_examples/hbc_staged"
describe Hbc::DSL::Preflight, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("basic-cask")) }
let(:dsl) { Hbc::DSL::Preflight.new(cask, Hbc::FakeSystemCommand) }
it_behaves_like Hbc::DSL::Base
diff --git a/Library/Homebrew/test/cask/dsl/uninstall_postflight_spec.rb b/Library/Homebrew/test/cask/dsl/uninstall_postflight_spec.rb
index f89a181ce..b2af700db 100644
--- a/Library/Homebrew/test/cask/dsl/uninstall_postflight_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/uninstall_postflight_spec.rb
@@ -1,7 +1,7 @@
require "test/support/helper/spec/shared_examples/hbc_dsl_base"
describe Hbc::DSL::UninstallPostflight, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("basic-cask")) }
let(:dsl) { Hbc::DSL::UninstallPostflight.new(cask, Hbc::FakeSystemCommand) }
it_behaves_like Hbc::DSL::Base
diff --git a/Library/Homebrew/test/cask/dsl/uninstall_preflight_spec.rb b/Library/Homebrew/test/cask/dsl/uninstall_preflight_spec.rb
index 15a0ea156..8e7fa47eb 100644
--- a/Library/Homebrew/test/cask/dsl/uninstall_preflight_spec.rb
+++ b/Library/Homebrew/test/cask/dsl/uninstall_preflight_spec.rb
@@ -2,7 +2,7 @@ require "test/support/helper/spec/shared_examples/hbc_dsl_base"
require "test/support/helper/spec/shared_examples/hbc_staged"
describe Hbc::DSL::UninstallPreflight, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/basic-cask.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("basic-cask")) }
let(:dsl) { Hbc::DSL::UninstallPreflight.new(cask, Hbc::FakeSystemCommand) }
it_behaves_like Hbc::DSL::Base
diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb
index 7f2207a87..28cf6f4b2 100644
--- a/Library/Homebrew/test/cask/dsl_spec.rb
+++ b/Library/Homebrew/test/cask/dsl_spec.rb
@@ -1,5 +1,5 @@
describe Hbc::DSL, :cask do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/#{token}.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path(token.to_s)) }
let(:token) { "basic-cask" }
context "stanzas" do
@@ -177,6 +177,36 @@ describe Hbc::DSL, :cask do
expect(cask.call.sha256).to eq("xyz789")
expect(cask.call.url.to_s).to eq("https://example.org/en-US.zip")
end
+
+ it "returns an empty array if no languages are specified" do
+ cask = lambda do
+ Hbc::Cask.new("cask-with-apps") do
+ url "https://example.org/file.zip"
+ end
+ end
+
+ expect(cask.call.languages).to be_empty
+ end
+
+ it "returns an array of available languages" do
+ cask = lambda do
+ Hbc::Cask.new("cask-with-apps") do
+ language "zh" do
+ sha256 "abc123"
+ "zh-CN"
+ end
+
+ language "en-US", default: true do
+ sha256 "xyz789"
+ "en-US"
+ end
+
+ url "https://example.org/file.zip"
+ end
+ end
+
+ expect(cask.call.languages).to eq(["zh", "en-US"])
+ end
end
describe "app stanza" do
@@ -186,12 +216,12 @@ describe Hbc::DSL, :cask do
app "Bar.app"
end
- expect(Array(cask.artifacts[:app])).to eq([["Foo.app"], ["Bar.app"]])
+ expect(cask.artifacts.map(&:to_s)).to eq(["Foo.app (App)", "Bar.app (App)"])
end
it "allow app stanzas to be empty" do
cask = Hbc::Cask.new("cask-with-no-apps")
- expect(Array(cask.artifacts[:app])).to eq([])
+ expect(cask.artifacts).to be_empty
end
end
@@ -219,7 +249,7 @@ describe Hbc::DSL, :cask do
pkg "Bar.pkg"
end
- expect(Array(cask.artifacts[:pkg])).to eq([["Foo.pkg"], ["Bar.pkg"]])
+ expect(cask.artifacts.map(&:to_s)).to eq(["Foo.pkg (Pkg)", "Bar.pkg (Pkg)"])
end
end
@@ -471,10 +501,10 @@ describe Hbc::DSL, :cask do
let(:token) { "with-installer-script" }
it "allows installer script to be specified" do
- expect(cask.artifacts[:installer].first.script[:executable]).to eq("/usr/bin/true")
- expect(cask.artifacts[:installer].first.script[:args]).to eq(["--flag"])
- expect(cask.artifacts[:installer].to_a[1].script[:executable]).to eq("/usr/bin/false")
- expect(cask.artifacts[:installer].to_a[1].script[:args]).to eq(["--flag"])
+ expect(cask.artifacts.to_a[0].path).to eq(Pathname("/usr/bin/true"))
+ expect(cask.artifacts.to_a[0].args[:args]).to eq(["--flag"])
+ expect(cask.artifacts.to_a[1].path).to eq(Pathname("/usr/bin/false"))
+ expect(cask.artifacts.to_a[1].args[:args]).to eq(["--flag"])
end
end
@@ -482,7 +512,9 @@ describe Hbc::DSL, :cask do
let(:token) { "with-installer-manual" }
it "allows installer manual to be specified" do
- expect(cask.artifacts[:installer].first.manual).to eq("Caffeine.app")
+ installer = cask.artifacts.first
+ expect(installer).to be_a(Hbc::Artifact::Installer::ManualInstaller)
+ expect(installer.path).to eq(cask.staged_path.join("Caffeine.app"))
end
end
end
@@ -492,7 +524,7 @@ describe Hbc::DSL, :cask do
let(:token) { "stage-only" }
it "allows stage_only stanza to be specified" do
- expect(cask.artifacts[:stage_only].first).to eq([true])
+ expect(cask.artifacts).to contain_exactly a_kind_of Hbc::Artifact::StageOnly
end
end
@@ -513,12 +545,12 @@ describe Hbc::DSL, :cask do
end
end
- describe "appdir" do
+ describe "#appdir" do
context "interpolation of the appdir in stanzas" do
let(:token) { "appdir-interpolation" }
it "is allowed" do
- expect(cask.artifacts[:binary].first).to eq(["#{Hbc.appdir}/some/path"])
+ expect(cask.artifacts.first.source).to eq(Hbc.appdir/"some/path")
end
end
@@ -531,10 +563,35 @@ describe Hbc::DSL, :cask do
binary "#{appdir}/some/path"
end
- expect(cask.artifacts[:binary].first).to eq(["#{original_appdir}/some/path"])
+ expect(cask.artifacts.first.source).to eq(original_appdir/"some/path")
ensure
Hbc.appdir = original_appdir
end
end
end
+
+ describe "#artifacts" do
+ it "sorts artifacts according to the preferable installation order" do
+ cask = Hbc::Cask.new("appdir-trailing-slash") do
+ postflight do
+ next
+ end
+
+ preflight do
+ next
+ end
+
+ binary "binary"
+
+ app "App.app"
+ end
+
+ expect(cask.artifacts.map(&:class).map(&:dsl_key)).to eq [
+ :preflight,
+ :app,
+ :binary,
+ :postflight,
+ ]
+ end
+ end
end
diff --git a/Library/Homebrew/test/cask/installer_spec.rb b/Library/Homebrew/test/cask/installer_spec.rb
index 6f7c6d3d7..2dc27f04c 100644
--- a/Library/Homebrew/test/cask/installer_spec.rb
+++ b/Library/Homebrew/test/cask/installer_spec.rb
@@ -5,7 +5,7 @@ describe Hbc::Installer, :cask do
}
it "downloads and installs a nice fresh Cask" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
Hbc::Installer.new(caffeine).install
@@ -14,7 +14,7 @@ describe Hbc::Installer, :cask do
end
it "works with dmg-based Casks" do
- asset = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-dmg.rb")
+ asset = Hbc::CaskLoader.load(cask_path("container-dmg"))
Hbc::Installer.new(asset).install
@@ -23,7 +23,7 @@ describe Hbc::Installer, :cask do
end
it "works with tar-gz-based Casks" do
- asset = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-tar-gz.rb")
+ asset = Hbc::CaskLoader.load(cask_path("container-tar-gz"))
Hbc::Installer.new(asset).install
@@ -32,7 +32,7 @@ describe Hbc::Installer, :cask do
end
it "works with xar-based Casks" do
- asset = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-xar.rb")
+ asset = Hbc::CaskLoader.load(cask_path("container-xar"))
Hbc::Installer.new(asset).install
@@ -41,7 +41,7 @@ describe Hbc::Installer, :cask do
end
it "works with pure bzip2-based Casks" do
- asset = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-bzip2.rb")
+ asset = Hbc::CaskLoader.load(cask_path("container-bzip2"))
Hbc::Installer.new(asset).install
@@ -50,7 +50,7 @@ describe Hbc::Installer, :cask do
end
it "works with pure gzip-based Casks" do
- asset = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-gzip.rb")
+ asset = Hbc::CaskLoader.load(cask_path("container-gzip"))
Hbc::Installer.new(asset).install
@@ -59,21 +59,21 @@ describe Hbc::Installer, :cask do
end
it "blows up on a bad checksum" do
- bad_checksum = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/bad-checksum.rb")
+ bad_checksum = Hbc::CaskLoader.load(cask_path("bad-checksum"))
expect {
Hbc::Installer.new(bad_checksum).install
}.to raise_error(Hbc::CaskSha256MismatchError)
end
it "blows up on a missing checksum" do
- missing_checksum = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/missing-checksum.rb")
+ missing_checksum = Hbc::CaskLoader.load(cask_path("missing-checksum"))
expect {
Hbc::Installer.new(missing_checksum).install
}.to raise_error(Hbc::CaskSha256MissingError)
end
it "installs fine if sha256 :no_check is used" do
- no_checksum = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/no-checksum.rb")
+ no_checksum = Hbc::CaskLoader.load(cask_path("no-checksum"))
Hbc::Installer.new(no_checksum).install
@@ -81,14 +81,14 @@ describe Hbc::Installer, :cask do
end
it "fails to install if sha256 :no_check is used with --require-sha" do
- no_checksum = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/no-checksum.rb")
+ no_checksum = Hbc::CaskLoader.load(cask_path("no-checksum"))
expect {
Hbc::Installer.new(no_checksum, require_sha: true).install
}.to raise_error(Hbc::CaskNoShasumError)
end
it "installs fine if sha256 :no_check is used with --require-sha and --force" do
- no_checksum = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/no-checksum.rb")
+ no_checksum = Hbc::CaskLoader.load(cask_path("no-checksum"))
Hbc::Installer.new(no_checksum, require_sha: true, force: true).install
@@ -96,7 +96,7 @@ describe Hbc::Installer, :cask do
end
it "prints caveats if they're present" do
- with_caveats = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-caveats.rb")
+ with_caveats = Hbc::CaskLoader.load(cask_path("with-caveats"))
expect {
Hbc::Installer.new(with_caveats).install
@@ -106,7 +106,7 @@ describe Hbc::Installer, :cask do
end
it "prints installer :manual instructions when present" do
- with_installer_manual = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-installer-manual.rb")
+ with_installer_manual = Hbc::CaskLoader.load(cask_path("with-installer-manual"))
expect {
Hbc::Installer.new(with_installer_manual).install
@@ -116,7 +116,7 @@ describe Hbc::Installer, :cask do
end
it "does not extract __MACOSX directories from zips" do
- with_macosx_dir = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-macosx-dir.rb")
+ with_macosx_dir = Hbc::CaskLoader.load(cask_path("with-macosx-dir"))
Hbc::Installer.new(with_macosx_dir).install
@@ -124,7 +124,7 @@ describe Hbc::Installer, :cask do
end
it "allows already-installed Casks which auto-update to be installed if force is provided" do
- with_auto_updates = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/auto-updates.rb")
+ with_auto_updates = Hbc::CaskLoader.load(cask_path("auto-updates"))
expect(with_auto_updates).not_to be_installed
@@ -137,7 +137,7 @@ describe Hbc::Installer, :cask do
# unlike the CLI, the internal interface throws exception on double-install
it "installer method raises an exception when already-installed Casks are attempted" do
- transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ transmission = Hbc::CaskLoader.load(cask_path("local-transmission"))
expect(transmission).not_to be_installed
@@ -151,7 +151,7 @@ describe Hbc::Installer, :cask do
end
it "allows already-installed Casks to be installed if force is provided" do
- transmission = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb")
+ transmission = Hbc::CaskLoader.load(cask_path("local-transmission"))
expect(transmission).not_to be_installed
@@ -163,7 +163,7 @@ describe Hbc::Installer, :cask do
end
it "works naked-pkg-based Casks" do
- naked_pkg = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/container-pkg.rb")
+ naked_pkg = Hbc::CaskLoader.load(cask_path("container-pkg"))
Hbc::Installer.new(naked_pkg).install
@@ -171,7 +171,7 @@ describe Hbc::Installer, :cask do
end
it "works properly with an overridden container :type" do
- naked_executable = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/naked-executable.rb")
+ naked_executable = Hbc::CaskLoader.load(cask_path("naked-executable"))
Hbc::Installer.new(naked_executable).install
@@ -179,7 +179,7 @@ describe Hbc::Installer, :cask do
end
it "works fine with a nested container" do
- nested_app = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/nested-app.rb")
+ nested_app = Hbc::CaskLoader.load(cask_path("nested-app"))
Hbc::Installer.new(nested_app).install
@@ -187,7 +187,7 @@ describe Hbc::Installer, :cask do
end
it "generates and finds a timestamped metadata directory for an installed Cask" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
Hbc::Installer.new(caffeine).install
@@ -196,7 +196,7 @@ describe Hbc::Installer, :cask do
end
it "generates and finds a metadata subdirectory for an installed Cask" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
Hbc::Installer.new(caffeine).install
@@ -208,7 +208,7 @@ describe Hbc::Installer, :cask do
describe "uninstall" do
it "fully uninstalls a Cask" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
installer = Hbc::Installer.new(caffeine)
installer.install
@@ -220,7 +220,7 @@ describe Hbc::Installer, :cask do
end
it "uninstalls all versions if force is set" do
- caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb")
+ caffeine = Hbc::CaskLoader.load(cask_path("local-caffeine"))
mutated_version = caffeine.version + ".1"
Hbc::Installer.new(caffeine).install
diff --git a/Library/Homebrew/test/cask/staged_spec.rb b/Library/Homebrew/test/cask/staged_spec.rb
index 73a909f35..0229018c7 100644
--- a/Library/Homebrew/test/cask/staged_spec.rb
+++ b/Library/Homebrew/test/cask/staged_spec.rb
@@ -3,7 +3,7 @@
# to be invoking bundle_identifier off of the installer instance.
describe "Operations on staged Casks", :cask do
describe "bundle ID" do
- let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-transmission.rb") }
+ let(:cask) { Hbc::CaskLoader.load(cask_path("local-transmission")) }
let(:installer) { Hbc::Installer.new(cask) }
it "fetches the bundle ID from a staged cask" do
installer.install
diff --git a/Library/Homebrew/test/cask/underscore_supporting_uri_spec.rb b/Library/Homebrew/test/cask/underscore_supporting_uri_spec.rb
deleted file mode 100644
index 49d3ea63f..000000000
--- a/Library/Homebrew/test/cask/underscore_supporting_uri_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-describe Hbc::UnderscoreSupportingURI, :cask do
- describe "parse" do
- it "works like normal on normal URLs" do
- uri = Hbc::UnderscoreSupportingURI.parse("http://example.com/TestCask.dmg")
- expect(uri).to eq(URI("http://example.com/TestCask.dmg"))
- end
-
- it "works just fine on URIs with underscores" do
- uri = Hbc::UnderscoreSupportingURI.parse("http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V3.0.0.dmg")
- expect(uri.host).to include("_")
- expect(uri.to_s).to eq("http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V3.0.0.dmg")
- end
- end
-end
diff --git a/Library/Homebrew/test/cleanup_spec.rb b/Library/Homebrew/test/cleanup_spec.rb
index 4e5e42efa..da262c5ca 100644
--- a/Library/Homebrew/test/cleanup_spec.rb
+++ b/Library/Homebrew/test/cleanup_spec.rb
@@ -5,6 +5,7 @@ require "pathname"
describe Homebrew::Cleanup do
let(:ds_store) { Pathname.new("#{HOMEBREW_PREFIX}/Library/.DS_Store") }
+ let(:sec_in_a_day) { 60 * 60 * 24 }
around(:each) do |example|
begin
@@ -104,14 +105,30 @@ describe Homebrew::Cleanup do
expect(f4).to be_installed
end
- specify "::cleanup_logs" do
- path = (HOMEBREW_LOGS/"delete_me")
- path.mkpath
- ARGV << "--prune=all"
+ describe "::cleanup_logs" do
+ let(:path) { (HOMEBREW_LOGS/"delete_me") }
- described_class.cleanup_logs
+ before do
+ path.mkpath
+ end
+
+ it "cleans all logs if prune all" do
+ ARGV << "--prune=all"
+ described_class.cleanup_logs
+ expect(path).not_to exist
+ end
- expect(path).not_to exist
+ it "cleans up logs if older than 14 days" do
+ allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - sec_in_a_day * 15)
+ described_class.cleanup_logs
+ expect(path).not_to exist
+ end
+
+ it "does not clean up logs less than 14 days old" do
+ allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - sec_in_a_day * 2)
+ described_class.cleanup_logs
+ expect(path).to exist
+ end
end
describe "::cleanup_cache" do
@@ -124,6 +141,15 @@ describe Homebrew::Cleanup do
expect(incomplete).not_to exist
end
+ it "cleans up 'glide_home'" do
+ glide_home = (HOMEBREW_CACHE/"glide_home")
+ glide_home.mkpath
+
+ described_class.cleanup_cache
+
+ expect(glide_home).not_to exist
+ end
+
it "cleans up 'java_cache'" do
java_cache = (HOMEBREW_CACHE/"java_cache")
java_cache.mkpath
@@ -141,5 +167,99 @@ describe Homebrew::Cleanup do
expect(npm_cache).not_to exist
end
+
+ it "cleans up all files and directories" do
+ git = (HOMEBREW_CACHE/"gist--git")
+ gist = (HOMEBREW_CACHE/"gist")
+ svn = (HOMEBREW_CACHE/"gist--svn")
+
+ git.mkpath
+ gist.mkpath
+ FileUtils.touch svn
+
+ allow(ARGV).to receive(:value).with("prune").and_return("all")
+
+ described_class.cleanup_cache
+
+ expect(git).not_to exist
+ expect(gist).to exist
+ expect(svn).not_to exist
+ end
+
+ it "does not clean up directories that are not VCS checkouts" do
+ git = (HOMEBREW_CACHE/"git")
+ git.mkpath
+ allow(ARGV).to receive(:value).with("prune").and_return("all")
+
+ described_class.cleanup_cache
+
+ expect(git).to exist
+ end
+
+ it "cleans up VCS checkout directories with modified time < prune time" do
+ foo = (HOMEBREW_CACHE/"--foo")
+ foo.mkpath
+ allow(ARGV).to receive(:value).with("prune").and_return("1")
+ allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - sec_in_a_day * 2)
+ described_class.cleanup_cache
+ expect(foo).not_to exist
+ end
+
+ it "does not clean up VCS checkout directories with modified time >= prune time" do
+ foo = (HOMEBREW_CACHE/"--foo")
+ foo.mkpath
+ allow(ARGV).to receive(:value).with("prune").and_return("1")
+ described_class.cleanup_cache
+ expect(foo).to exist
+ end
+
+ context "cleans old files in HOMEBREW_CACHE" do
+ let(:bottle) { (HOMEBREW_CACHE/"testball-0.0.1.bottle.tar.gz") }
+ let(:testball) { (HOMEBREW_CACHE/"testball-0.0.1") }
+
+ before(:each) do
+ FileUtils.touch(bottle)
+ FileUtils.touch(testball)
+ (HOMEBREW_CELLAR/"testball"/"0.0.1").mkpath
+ FileUtils.touch(CoreTap.instance.formula_dir/"testball.rb")
+ end
+
+ it "cleans up file if outdated" do
+ allow(Utils::Bottles).to receive(:file_outdated?).with(any_args).and_return(true)
+ described_class.cleanup_cache
+ expect(bottle).not_to exist
+ expect(testball).not_to exist
+ end
+
+ it "cleans up file if ARGV has -s and formula not installed" do
+ ARGV << "-s"
+ described_class.cleanup_cache
+ expect(bottle).not_to exist
+ expect(testball).not_to exist
+ end
+
+ it "cleans up file if stale" do
+ described_class.cleanup_cache
+ expect(bottle).not_to exist
+ expect(testball).not_to exist
+ end
+ end
+ end
+
+ describe "::prune?" do
+ before do
+ foo.mkpath
+ end
+
+ let(:foo) { HOMEBREW_CACHE/"foo" }
+
+ it "returns true when path_modified_time < days_default" do
+ allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - sec_in_a_day * 2)
+ expect(described_class.prune?(foo, days_default: "1")).to be_truthy
+ end
+
+ it "returns false when path_modified_time >= days_default" do
+ expect(described_class.prune?(foo, days_default: "2")).to be_falsey
+ end
end
end
diff --git a/Library/Homebrew/test/cmd/commands_spec.rb b/Library/Homebrew/test/cmd/commands_spec.rb
index cf6f56740..46ed3ddcf 100644
--- a/Library/Homebrew/test/cmd/commands_spec.rb
+++ b/Library/Homebrew/test/cmd/commands_spec.rb
@@ -68,7 +68,7 @@ describe Homebrew do
expect(cmds).to include("t1"), "Executable files should be included"
expect(cmds).to include("t2"), "Executable Ruby files should be included"
- expect(cmds).not_to include("t3"), "Executable files with a non Ruby extension shoudn't be included"
+ expect(cmds).not_to include("t3"), "Executable files with a non Ruby extension shouldn't be included"
expect(cmds).not_to include("t4"), "Non-executable files shouldn't be included"
end
end
diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb
index 5a4070492..cf9453af2 100644
--- a/Library/Homebrew/test/cmd/home_spec.rb
+++ b/Library/Homebrew/test/cmd/home_spec.rb
@@ -7,10 +7,10 @@ describe "brew home", :integration_test do
end
it "opens the homepage for a given Formula" do
- setup_test_formula "testball"
+ setup_test_formula "testballhome"
- expect { brew "home", "testball", "HOMEBREW_BROWSER" => "echo" }
- .to output("#{Formula["testball"].homepage}\n").to_stdout
+ expect { brew "home", "testballhome", "HOMEBREW_BROWSER" => "echo" }
+ .to output("#{Formula["testballhome"].homepage}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
diff --git a/Library/Homebrew/test/cmd/search_remote_tap_spec.rb b/Library/Homebrew/test/cmd/search_remote_tap_spec.rb
index b0beb122c..eb256b924 100644
--- a/Library/Homebrew/test/cmd/search_remote_tap_spec.rb
+++ b/Library/Homebrew/test/cmd/search_remote_tap_spec.rb
@@ -2,6 +2,9 @@ require "cmd/search"
describe Homebrew do
specify "#search_taps" do
+ # Otherwise the tested method returns [], regardless of our stub
+ ENV.delete("HOMEBREW_NO_GITHUB_API")
+
json_response = {
"items" => [
{
diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb
index 06b7073d8..36ddde3e1 100644
--- a/Library/Homebrew/test/cmd/search_spec.rb
+++ b/Library/Homebrew/test/cmd/search_spec.rb
@@ -1,6 +1,7 @@
describe "brew search", :integration_test do
before(:each) do
setup_test_formula "testball"
+ setup_remote_tap "caskroom/cask"
end
it "lists all available Formulae when no argument is given" do
@@ -13,7 +14,7 @@ describe "brew search", :integration_test do
it "supports searching by name" do
expect { brew "search", "testball" }
.to output(/testball/).to_stdout
- .and not_to_output.to_stderr
+ .and output(/Searching/).to_stderr
.and be_a_success
end
@@ -24,6 +25,13 @@ describe "brew search", :integration_test do
.and be_a_success
end
+ it "falls back to a GitHub tap search when no formula is found", :needs_network do
+ expect { brew "search", "caskroom/cask/firefox" }
+ .to output(/firefox/).to_stdout
+ .and output(/Searching/).to_stderr
+ .and be_a_success
+ end
+
describe "--desc" do
let(:desc_cache) { HOMEBREW_CACHE/"desc_cache.json" }
@@ -44,8 +52,8 @@ describe "brew search", :integration_test do
"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",
+ "fedora" => "https://apps.fedoraproject.org/packages/s/testball",
+ "ubuntu" => "https://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" }
diff --git a/Library/Homebrew/test/dependency_expansion_spec.rb b/Library/Homebrew/test/dependency_expansion_spec.rb
index f955237a9..d6ecdf552 100644
--- a/Library/Homebrew/test/dependency_expansion_spec.rb
+++ b/Library/Homebrew/test/dependency_expansion_spec.rb
@@ -69,7 +69,7 @@ describe Dependency do
end
end
- it "merges dependencies and perserves env_proc" do
+ it "merges dependencies and preserves 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"))
diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb
index 037865fdf..3e99bd06b 100644
--- a/Library/Homebrew/test/dev-cmd/audit_spec.rb
+++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb
@@ -150,70 +150,6 @@ describe FormulaAuditor do
end
end
- describe "#audit_class" do
- specify "missing test" do
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_class
- expect(fa.problems).to eq([])
-
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_class
- expect(fa.problems).to eq(["A `test do` test block should be added"])
- end
-
- specify "GithubGistFormula", :needs_compat do
- ENV.delete("HOMEBREW_DEVELOPER")
-
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < GithubGistFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_class
- expect(fa.problems)
- .to eq(["GithubGistFormula is deprecated, use Formula instead"])
- end
-
- specify "ScriptFileFormula", :needs_compat do
- ENV.delete("HOMEBREW_DEVELOPER")
-
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < ScriptFileFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_class
- expect(fa.problems)
- .to eq(["ScriptFileFormula is deprecated, use Formula instead"])
- end
-
- specify "AmazonWebServicesFormula", :needs_compat do
- ENV.delete("HOMEBREW_DEVELOPER")
-
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < AmazonWebServicesFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_class
- expect(fa.problems)
- .to eq(["AmazonWebServicesFormula is deprecated, use Formula instead"])
- end
- end
-
describe "#line_problems" do
specify "pkgshare" do
fa = formula_auditor "foo", <<-EOS.undent, strict: true
diff --git a/Library/Homebrew/test/download_strategies_spec.rb b/Library/Homebrew/test/download_strategies_spec.rb
index 8c376a649..06d6fa855 100644
--- a/Library/Homebrew/test/download_strategies_spec.rb
+++ b/Library/Homebrew/test/download_strategies_spec.rb
@@ -200,6 +200,17 @@ describe GitDownloadStrategy do
end
end
+describe CurlDownloadStrategy do
+ subject { described_class.new(name, resource) }
+ let(:name) { "foo" }
+ let(:url) { "http://example.com/foo.tar.gz" }
+ let(:resource) { double(Resource, url: url, mirrors: [], specs: { user: "download:123456" }, version: nil) }
+
+ it "parses the opts and sets the corresponding args" do
+ expect(subject.send(:_curl_opts)).to eq(["--user", "download:123456"])
+ end
+end
+
describe DownloadStrategyDetector do
describe "::detect" do
subject { described_class.detect(url) }
diff --git a/Library/Homebrew/test/exceptions_spec.rb b/Library/Homebrew/test/exceptions_spec.rb
index 33547ea32..0a8313355 100644
--- a/Library/Homebrew/test/exceptions_spec.rb
+++ b/Library/Homebrew/test/exceptions_spec.rb
@@ -181,8 +181,8 @@ describe DuplicateResourceError do
its(:to_s) { is_expected.to eq("Resource <resource foo> is defined more than once") }
end
-describe BottleVersionMismatchError do
- subject { described_class.new("/foo.bottle.tar.gz", "1.0", formula, "1.1") }
+describe BottleFormulaUnavailableError do
+ subject { described_class.new("/foo.bottle.tar.gz", "foo/1.0/.brew/foo.rb") }
let(:formula) { double(Formula, full_name: "foo") }
- its(:to_s) { is_expected.to match(/Bottle version mismatch/) }
+ its(:to_s) { is_expected.to match(/This bottle does not contain the formula file/) }
end
diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb
index 7365b2758..7b729312b 100644
--- a/Library/Homebrew/test/formula_installer_spec.rb
+++ b/Library/Homebrew/test/formula_installer_spec.rb
@@ -107,7 +107,7 @@ describe FormulaInstaller do
end
EOS
- Formulary::FORMULAE.delete(dep_path)
+ Formulary.cache.delete(dep_path)
dependency = Formulary.factory(dep_name)
dependent = formula do
diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb
index 234ebc93c..3180ad9a7 100644
--- a/Library/Homebrew/test/formulary_spec.rb
+++ b/Library/Homebrew/test/formulary_spec.rb
@@ -14,7 +14,7 @@ describe Formulary do
bottle do
cellar :any_skip_relocation
root_url "file://#{bottle_dir}"
- sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :#{Utils::Bottles.tag}
+ sha256 "d48bbbe583dcfbfa608579724fc6f0328b3cd316935c6ea22f134610aaf2952f" => :#{Utils::Bottles.tag}
end
def install
diff --git a/Library/Homebrew/test/locale_spec.rb b/Library/Homebrew/test/locale_spec.rb
index 9e4d09e83..9c684f0e7 100644
--- a/Library/Homebrew/test/locale_spec.rb
+++ b/Library/Homebrew/test/locale_spec.rb
@@ -9,6 +9,10 @@ describe Locale do
expect(described_class.parse("zh-CN-Hans")).to eql(described_class.new("zh", "CN", "Hans"))
end
+ it "correctly parses a string with a UN M.49 region code" do
+ expect(described_class.parse("es-419")).to eql(described_class.new("es", "419", nil))
+ end
+
context "raises a ParserError when given" do
it "an empty string" do
expect { described_class.parse("") }.to raise_error(Locale::ParserError)
diff --git a/Library/Homebrew/test/missing_formula_spec.rb b/Library/Homebrew/test/missing_formula_spec.rb
index a48f12ecd..0a905004b 100644
--- a/Library/Homebrew/test/missing_formula_spec.rb
+++ b/Library/Homebrew/test/missing_formula_spec.rb
@@ -82,12 +82,6 @@ describe Homebrew::MissingFormula do
it { is_expected.to be_blacklisted }
end
- context "clojure" do
- subject { "clojure" }
-
- it { is_expected.to be_blacklisted }
- end
-
context "gfortran" do
subject { "gfortran" }
diff --git a/Library/Homebrew/test/os/mac/diagnostic_spec.rb b/Library/Homebrew/test/os/mac/diagnostic_spec.rb
index d6186e46b..83d95c2ef 100644
--- a/Library/Homebrew/test/os/mac/diagnostic_spec.rb
+++ b/Library/Homebrew/test/os/mac/diagnostic_spec.rb
@@ -47,15 +47,10 @@ describe Homebrew::Diagnostic::Checks do
end
specify "#check_ruby_version" do
- allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.13"))
- stub_const("RUBY_VERSION", "2.3.3p222")
+ allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.12"))
+ stub_const("RUBY_VERSION", "1.8.6")
expect(subject.check_ruby_version)
- .to match <<-EOS.undent
- Ruby version 2.3.3p222 is unsupported on 10.13. Homebrew
- is developed and tested on Ruby 2.0, and may not work correctly
- on other Rubies. Patches are accepted as long as they don't cause breakage
- on supported Rubies.
- EOS
+ .to match "Ruby version 1.8.6 is unsupported on 10.12"
end
end
diff --git a/Library/Homebrew/test/pathname_spec.rb b/Library/Homebrew/test/pathname_spec.rb
index 0bc19c5ac..69314e5f4 100644
--- a/Library/Homebrew/test/pathname_spec.rb
+++ b/Library/Homebrew/test/pathname_spec.rb
@@ -295,7 +295,7 @@ describe FileUtils do
let(:dst) { mktmpdir }
describe "#mkdir" do
- it "creates indermediate directories" do
+ it "creates intermediate 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"
diff --git a/Library/Homebrew/test/requirement_spec.rb b/Library/Homebrew/test/requirement_spec.rb
index 71372aa69..11a3da8f4 100644
--- a/Library/Homebrew/test/requirement_spec.rb
+++ b/Library/Homebrew/test/requirement_spec.rb
@@ -48,7 +48,7 @@ describe Requirement do
it { is_expected.to be_fatal }
end
- context "#fatal is ommitted" do
+ context "#fatal is omitted" do
it { is_expected.not_to be_fatal }
end
end
@@ -184,7 +184,7 @@ describe Requirement do
it { is_expected.to have_a_default_formula }
end
- context "#default_formula ommitted" do
+ context "#default_formula omitted" do
it { is_expected.not_to have_a_default_formula }
end
end
diff --git a/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb b/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
index 563f7ad4b..b1afdc3f9 100644
--- a/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/bottle_block_cop_spec.rb
@@ -24,7 +24,7 @@ describe RuboCop::Cop::FormulaAuditStrict::BottleBlock do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -60,7 +60,7 @@ describe RuboCop::Cop::FormulaAuditStrict::BottleBlock do
end
EOS
- new_source = autocorrect_source(cop, source)
+ new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
diff --git a/Library/Homebrew/test/rubocops/caveats_cop_spec.rb b/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
index d44808a5d..4dbe65cfb 100644
--- a/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/caveats_cop_spec.rb
@@ -25,7 +25,7 @@ describe RuboCop::Cop::FormulaAudit::Caveats do
column: 5,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
diff --git a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
index 644152c32..2f508bbf5 100644
--- a/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/checksum_cop_spec.rb
@@ -34,7 +34,7 @@ describe RuboCop::Cop::FormulaAudit::Checksum do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -68,7 +68,7 @@ describe RuboCop::Cop::FormulaAudit::Checksum do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -102,7 +102,7 @@ describe RuboCop::Cop::FormulaAudit::Checksum do
column: 31,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -142,7 +142,7 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
column: 20,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -175,7 +175,7 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
column: 12,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -215,7 +215,7 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
end
EOS
- new_source = autocorrect_source(cop, source)
+ new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
diff --git a/Library/Homebrew/test/rubocops/class_cop_spec.rb b/Library/Homebrew/test/rubocops/class_cop_spec.rb
new file mode 100644
index 000000000..59252587c
--- /dev/null
+++ b/Library/Homebrew/test/rubocops/class_cop_spec.rb
@@ -0,0 +1,81 @@
+require "rubocop"
+require "rubocop/rspec/support"
+require_relative "../../extend/string"
+require_relative "../../rubocops/class_cop"
+
+describe RuboCop::Cop::FormulaAudit::ClassName do
+ subject(:cop) { described_class.new }
+
+ context "When auditing formula" do
+ it "with deprecated inheritance" do
+ formulas = [{
+ "class" => "GithubGistFormula",
+ }, {
+ "class" => "ScriptFileFormula",
+ }, {
+ "class" => "AmazonWebServicesFormula",
+ }]
+
+ formulas.each do |formula|
+ source = <<-EOS.undent
+ class Foo < #{formula["class"]}
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ EOS
+
+ expected_offenses = [{ message: "#{formula["class"]} is deprecated, use Formula instead",
+ severity: :convention,
+ line: 1,
+ column: 12,
+ source: source }]
+
+ inspect_source(source)
+
+ expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
+ expect_offense(expected, actual)
+ end
+ end
+ end
+
+ it "with deprecated inheritance and autocorrect" do
+ source = <<-EOS.undent
+ class Foo < AmazonWebServicesFormula
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ EOS
+ corrected_source = <<-EOS.undent
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ EOS
+
+ new_source = autocorrect_source(source)
+ expect(new_source).to eq(corrected_source)
+ end
+ end
+end
+
+describe RuboCop::Cop::FormulaAuditStrict::Test do
+ subject(:cop) { described_class.new }
+
+ context "When auditing formula" do
+ it "without a test block" do
+ source = <<-EOS.undent
+ class Foo < Formula
+ url 'http://example.com/foo-1.0.tgz'
+ end
+ EOS
+ expected_offenses = [{ message: described_class::MSG,
+ severity: :convention,
+ line: 1,
+ column: 0,
+ source: source }]
+
+ inspect_source(source)
+
+ expected_offenses.zip(cop.offenses).each do |expected, actual|
+ expect_offense(expected, actual)
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
index 25467c635..f093f4927 100644
--- a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb
@@ -21,7 +21,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -47,7 +47,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -74,7 +74,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -99,7 +99,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -129,7 +129,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
end
EOS
- corrected_source = autocorrect_source(cop, source)
+ corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
@@ -156,7 +156,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
end
end
EOS
- corrected_source = autocorrect_source(cop, source)
+ corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
end
diff --git a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
index fd635a126..9fbe15904 100644
--- a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb
@@ -23,7 +23,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -46,7 +46,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -70,7 +70,7 @@ describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
diff --git a/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
index 4fbab6c9e..8874ecc96 100644
--- a/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb
@@ -22,7 +22,7 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source, "/homebrew-core/Formula/foo@2.0.rb")
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -36,7 +36,7 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
desc 'Bar'
end
EOS
- inspect_source(cop, source)
+ inspect_source(source, "/homebrew-core/Formula/foo@2.0.rb")
expect(cop.offenses).to eq([])
end
end
diff --git a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
index 74ce478fb..ac8893e18 100644
--- a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb
@@ -20,7 +20,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
column: 0,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -37,7 +37,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
msg = <<-EOS.undent
Description is too long. "name: desc" should be less than 80 characters.
- Length is calculated as Foo + desc. (currently 95)
+ Length is calculated as foo + desc. (currently 95)
EOS
expected_offenses = [{ message: msg,
severity: :convention,
@@ -45,7 +45,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source, "/homebrew-core/Formula/foo.rb")
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -62,7 +62,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
msg = <<-EOS.undent
Description is too long. "name: desc" should be less than 80 characters.
- Length is calculated as Foo + desc. (currently 98)
+ Length is calculated as foo + desc. (currently 98)
EOS
expected_offenses = [{ message: msg,
severity: :convention,
@@ -70,7 +70,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source, "/homebrew-core/Formula/foo.rb")
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -96,7 +96,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
column: 8,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -116,7 +116,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
column: 8,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -136,7 +136,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
column: 8,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -156,7 +156,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
column: 8,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source, "/homebrew-core/Formula/foo.rb")
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
@@ -176,7 +176,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do
end
EOS
- corrected_source = autocorrect_source(cop, source)
+ corrected_source = autocorrect_source(source, "/homebrew-core/Formula/foo.rb")
expect(corrected_source).to eq(correct_source)
end
end
diff --git a/Library/Homebrew/test/rubocops/homepage_cop_spec.rb b/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
index c03efd825..6c7f248ba 100644
--- a/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/homepage_cop_spec.rb
@@ -20,7 +20,7 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
column: 0,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -41,7 +41,7 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -72,7 +72,7 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
end
EOS
- inspect_source(cop, source)
+ inspect_source(source)
if homepage =~ %r{http:\/\/www\.freedesktop\.org}
if homepage =~ /Software/
expected_offenses = [{ message: "#{homepage} should be styled " \
diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb
index 6f1f8a48c..962827ca3 100644
--- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb
@@ -42,7 +42,7 @@ describe RuboCop::Cop::FormulaAudit::Lines do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expect_offense(expected, actual)
@@ -50,12 +50,6 @@ describe RuboCop::Cop::FormulaAudit::Lines do
end
end
end
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
- end
end
describe RuboCop::Cop::FormulaAudit::ClassInheritance do
@@ -76,19 +70,13 @@ describe RuboCop::Cop::FormulaAudit::ClassInheritance do
column: 10,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source, '/homebrew-core/Formula/foo.rb')
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
end
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
- end
end
describe RuboCop::Cop::FormulaAudit::Comments do
@@ -104,13 +92,13 @@ describe RuboCop::Cop::FormulaAudit::Comments do
end
EOS
- expected_offenses = [{ message: "Commented cmake call found",
+ expected_offenses = [{ message: "Please remove default template comments",
severity: :convention,
line: 4,
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -132,7 +120,7 @@ describe RuboCop::Cop::FormulaAudit::Comments do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -148,25 +136,19 @@ describe RuboCop::Cop::FormulaAudit::Comments do
end
EOS
- expected_offenses = [{ message: 'Commented-out dep "foo"',
+ expected_offenses = [{ message: 'Commented-out dependency "foo"',
severity: :convention,
line: 4,
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
end
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
- end
end
describe RuboCop::Cop::FormulaAudit::Miscellaneous do
@@ -188,7 +170,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -212,7 +194,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -237,7 +219,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -264,7 +246,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 7,
source: source }]
- inspect_source(cop, source, "/homebrew-core/")
+ inspect_source(source, "/homebrew-core/")
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -292,7 +274,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -317,7 +299,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -342,7 +324,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -358,14 +340,16 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
end
EOS
- expected_offenses = [{ message: "`skip_clean :all` is deprecated; brew no longer strips symbols\n" \
- "\tPass explicit paths to prevent Homebrew from removing empty folders.",
+ expected_offenses = [{ message: <<-EOS.undent.chomp,
+ `skip_clean :all` is deprecated; brew no longer strips symbols
+ Pass explicit paths to prevent Homebrew from removing empty folders.
+ EOS
severity: :convention,
line: 4,
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -383,19 +367,34 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
end
EOS
- expected_offenses = [{ message: "macOS has been 64-bit only so build.universal? is deprecated.",
+ expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so build.universal? is deprecated.",
severity: :convention,
line: 4,
column: 5,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+ it "with build.universal? exempted formula" do
+ source = <<-EOS.undent
+ class Wine < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ if build.universal?
+ "foo"
+ end
+ end
+ EOS
+
+ inspect_source(source, "/homebrew-core/Formula/wine.rb")
+ expect(cop.offenses).to eq([])
+ end
+
it "with ENV.universal_binary" do
source = <<-EOS.undent
class Foo < Formula
@@ -413,14 +412,14 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 5,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
- it "with ENV.universal_binary" do
+ it "with ENV.universal_binary 2" do
source = <<-EOS.undent
class Foo < Formula
desc "foo"
@@ -437,7 +436,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 5,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -459,13 +458,26 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 10,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+ it "with ruby-macho alternatives audit exempted formula" do
+ source = <<-EOS.undent
+ class Cctools < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "install_name_tool", "-id"
+ end
+ EOS
+
+ inspect_source(source, "/homebrew-core/Formula/cctools.rb")
+ expect(cop.offenses).to eq([])
+ end
+
it "with npm install without language::Node args" do
source = <<-EOS.undent
class Foo < Formula
@@ -478,16 +490,29 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
expected_offenses = [{ message: "Use Language::Node for npm install args",
severity: :convention,
line: 4,
- column: 17,
+ column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+ it "with npm install without language::Node args in kibana" do
+ source = <<-EOS.undent
+ class KibanaAT44 < Formula
+ desc "foo"
+ url 'http://example.com/foo-1.0.tgz'
+ system "npm", "install"
+ end
+ EOS
+
+ inspect_source(source, "/homebrew-core/Formula/kibana@4.4.rb")
+ expect(cop.offenses).to eq([])
+ end
+
it "with assert include" do
source = <<-EOS.undent
class Foo < Formula
@@ -503,7 +528,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 9,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -525,12 +550,13 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 13,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+
it "with old style OS check" do
source = <<-EOS.undent
class Foo < Formula
@@ -546,7 +572,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 21,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -569,12 +595,13 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 13,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+
it "with system call to fileUtils Method" do
source = <<-EOS.undent
class Foo < Formula
@@ -590,12 +617,13 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 10,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+
it "with a top-level function def " do
source = <<-EOS.undent
def test
@@ -613,7 +641,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 0,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -637,7 +665,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 18,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -661,7 +689,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 18,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -685,7 +713,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -709,7 +737,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -733,7 +761,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 30,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -757,7 +785,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 27,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -781,7 +809,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 30,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -805,7 +833,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 30,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -829,7 +857,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -853,7 +881,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 22,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -877,7 +905,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 12,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -901,7 +929,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 12,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -925,7 +953,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 28,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -949,7 +977,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 28,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -973,7 +1001,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 17,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -997,7 +1025,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 18,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1021,12 +1049,13 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 47,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
+
it "with formula path shortcut long form 3" do
source = <<-EOS.undent
class Foo < Formula
@@ -1044,7 +1073,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 46,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1066,7 +1095,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 24,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1088,7 +1117,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 10,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1110,7 +1139,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 13,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1134,7 +1163,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 5,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1158,7 +1187,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1182,7 +1211,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 26,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1206,7 +1235,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 14,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1228,7 +1257,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1250,7 +1279,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -1272,18 +1301,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
-
- end
- def expect_offense(expected, actual)
- expect(actual.message).to eq(expected[:message])
- expect(actual.severity).to eq(expected[:severity])
- expect(actual.line).to eq(expected[:line])
- expect(actual.column).to eq(expected[:column])
end
end
diff --git a/Library/Homebrew/test/rubocops/options_cop_spec.rb b/Library/Homebrew/test/rubocops/options_cop_spec.rb
index b89b3d9b5..c27389a68 100644
--- a/Library/Homebrew/test/rubocops/options_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/options_cop_spec.rb
@@ -21,7 +21,7 @@ describe RuboCop::Cop::FormulaAudit::Options do
column: 10,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -48,7 +48,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Options do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -72,7 +72,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Options do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -95,7 +95,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Options do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -122,7 +122,7 @@ describe RuboCop::Cop::NewFormulaAudit::Options do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
diff --git a/Library/Homebrew/test/rubocops/patches_cop_spec.rb b/Library/Homebrew/test/rubocops/patches_cop_spec.rb
index 4bd79bf35..4f9ca2df8 100644
--- a/Library/Homebrew/test/rubocops/patches_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/patches_cop_spec.rb
@@ -13,7 +13,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
url 'http://example.com/foo-1.0.tgz'
end
EOS
- inspect_source(cop, source)
+ inspect_source(source)
expect(cop.offenses).to eq([])
end
@@ -28,13 +28,13 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
EOS
- expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method",
- severity: :convention,
- line: 4,
- column: 2,
- source: source }]
+ expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method",
+ severity: :convention,
+ line: 4,
+ column: 2,
+ source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -48,6 +48,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
"http://trac.macports.org/export/102865/trunk/dports/mail/uudeview/files/inews.c.patch",
"http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=patch-libunac1.txt;att=1;bug=623340",
"https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch",
+ "https://github.com/dlang/dub/pull/1221.patch",
]
patch_urls.each do |patch_url|
source = <<-EOS.undent
@@ -60,42 +61,65 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
EOS
- inspect_source(cop, source)
- if patch_url =~ %r{/raw\.github\.com/}
- expected_offenses = [{ message: "GitHub/Gist patches should specify a revision:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 12,
- source: source }]
+ inspect_source(source)
+ expected_offense = if patch_url =~ %r{/raw\.github\.com/}
+ [{ message: <<-EOS.undent.chomp,
+ GitHub/Gist patches should specify a revision:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 12,
+ source: source }]
elsif patch_url =~ %r{macports/trunk}
- expected_offenses = [{ message: "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 33,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ MacPorts patches should specify a revision instead of trunk:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 33,
+ source: source }]
elsif patch_url =~ %r{^http://trac\.macports\.org}
- expected_offenses = [{ message: "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ Patches from MacPorts Trac should be https://, not http:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 5,
+ source: source }]
elsif patch_url =~ %r{^http://bugs\.debian\.org}
- expected_offenses = [{ message: "Patches from Debian should be https://, not http:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ Patches from Debian should be https://, not http:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 5,
+ source: source }]
elsif patch_url =~ %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}
- expected_offenses = [{ message: "use GitHub pull request URLs:\n"\
- " https://github.com/foo/foo-bar/pull/100.patch\n"\
- "Rather than patch-diff:\n"\
- " https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch\n",
- severity: :convention,
- line: 5,
- column: 5,
- source: source }]
+ [{ message: <<-EOS.undent,
+ use GitHub pull request URLs:
+ https://github.com/foo/foo-bar/pull/100.patch
+ Rather than patch-diff:
+ https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 5,
+ source: source }]
+ elsif patch_url =~ %r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)}
+ [{ message: <<-EOS.undent,
+ GitHub patches should use the full_index parameter:
+ #{patch_url}?full_index=1
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 5,
+ source: source }]
end
- expected_offenses.zip([cop.offenses.last]).each do |expected, actual|
+ expected_offense.zip([cop.offenses.last]).each do |expected, actual|
expect_offense(expected, actual)
end
end
@@ -116,19 +140,21 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
EOS
- expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method",
- severity: :convention,
- line: 4,
- column: 2,
- source: source },
- { message: "Patches from MacPorts Trac should be https://, not http:\n"\
- "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/",
- severity: :convention,
- line: 8,
- column: 26,
- source: source }]
+ expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method",
+ severity: :convention,
+ line: 4,
+ column: 2,
+ source: source },
+ { message: <<-EOS.undent.chomp,
+ Patches from MacPorts Trac should be https://, not http:
+ http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/
+ EOS
+ severity: :convention,
+ line: 8,
+ column: 26,
+ source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -157,42 +183,56 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
EOS
- inspect_source(cop, source)
- if patch_url =~ %r{/raw\.github\.com/}
- expected_offenses = [{ message: "GitHub/Gist patches should specify a revision:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 16,
- source: source }]
+ inspect_source(source)
+ expected_offense = if patch_url =~ %r{/raw\.github\.com/}
+ [{ message: <<-EOS.undent.chomp,
+ GitHub/Gist patches should specify a revision:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 16,
+ source: source }]
elsif patch_url =~ %r{macports/trunk}
- expected_offenses = [{ message: "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 37,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ MacPorts patches should specify a revision instead of trunk:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 37,
+ source: source }]
elsif patch_url =~ %r{^http://trac\.macports\.org}
- expected_offenses = [{ message: "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 9,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ Patches from MacPorts Trac should be https://, not http:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 9,
+ source: source }]
elsif patch_url =~ %r{^http://bugs\.debian\.org}
- expected_offenses = [{ message: "Patches from Debian should be https://, not http:\n#{patch_url}",
- severity: :convention,
- line: 5,
- column: 9,
- source: source }]
+ [{ message: <<-EOS.undent.chomp,
+ Patches from Debian should be https://, not http:
+ #{patch_url}
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 9,
+ source: source }]
elsif patch_url =~ %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}
- expected_offenses = [{ message: "use GitHub pull request URLs:\n"\
- " https://github.com/foo/foo-bar/pull/100.patch\n"\
- "Rather than patch-diff:\n"\
- " https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch\n",
- severity: :convention,
- line: 5,
- column: 9,
- source: source }]
+ [{ message: <<-EOS.undent,
+ use GitHub pull request URLs:
+ https://github.com/foo/foo-bar/pull/100.patch
+ Rather than patch-diff:
+ https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch
+ EOS
+ severity: :convention,
+ line: 5,
+ column: 9,
+ source: source }]
end
- expected_offenses.zip([cop.offenses.last]).each do |expected, actual|
+ expected_offense.zip([cop.offenses.last]).each do |expected, actual|
expect_offense(expected, actual)
end
end
diff --git a/Library/Homebrew/test/rubocops/text_cop_spec.rb b/Library/Homebrew/test/rubocops/text_cop_spec.rb
index b218e9c25..490801770 100644
--- a/Library/Homebrew/test/rubocops/text_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/text_cop_spec.rb
@@ -7,6 +7,54 @@ describe RuboCop::Cop::FormulaAudit::Text do
subject(:cop) { described_class.new }
context "When auditing formula text" do
+ it "with both openssl and libressl optional dependencies" do
+ source = <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+
+ depends_on "openssl"
+ depends_on "libressl" => :optional
+ end
+ EOS
+
+ expected_offenses = [{ message: "Formulae should not depend on both OpenSSL and LibreSSL (even optionally).",
+ severity: :convention,
+ line: 6,
+ column: 2,
+ source: source }]
+
+ inspect_source(source)
+
+ expected_offenses.zip(cop.offenses).each do |expected, actual|
+ expect_offense(expected, actual)
+ end
+ end
+
+ it "with both openssl and libressl dependencies" do
+ source = <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+
+ depends_on "openssl"
+ depends_on "libressl"
+ end
+ EOS
+
+ expected_offenses = [{ message: "Formulae should not depend on both OpenSSL and LibreSSL (even optionally).",
+ severity: :convention,
+ line: 6,
+ column: 2,
+ source: source }]
+
+ inspect_source(source)
+
+ expected_offenses.zip(cop.offenses).each do |expected, actual|
+ expect_offense(expected, actual)
+ end
+ end
+
it "When xcodebuild is called without SYMROOT" do
source = <<-EOS.undent
class Foo < Formula
@@ -25,7 +73,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -50,7 +98,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -75,7 +123,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -100,7 +148,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -125,7 +173,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -162,7 +210,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -189,7 +237,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 0,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -219,7 +267,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
@@ -244,7 +292,7 @@ describe RuboCop::Cop::FormulaAudit::Text do
column: 4,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
diff --git a/Library/Homebrew/test/rubocops/urls_cop_spec.rb b/Library/Homebrew/test/rubocops/urls_cop_spec.rb
index 280da6314..ad939a1a2 100644
--- a/Library/Homebrew/test/rubocops/urls_cop_spec.rb
+++ b/Library/Homebrew/test/rubocops/urls_cop_spec.rb
@@ -54,8 +54,10 @@ describe RuboCop::Cop::FormulaAudit::Urls do
"col" => 2,
}, {
"url" => "http://prdownloads.sourceforge.net/foo/foo-1.tar.gz",
- "msg" => "Don't use prdownloads in SourceForge urls (url is http://prdownloads.sourceforge.net/foo/foo-1.tar.gz).\n" \
- "\tSee: http://librelist.com/browser/homebrew/2011/1/12/prdownloads-is-bad/",
+ "msg" => <<-EOS.undent.chomp,
+ Don't use prdownloads in SourceForge urls (url is http://prdownloads.sourceforge.net/foo/foo-1.tar.gz).
+ See: http://librelist.com/browser/homebrew/2011/1/12/prdownloads-is-bad/
+ EOS
"col" => 2,
}, {
"url" => "http://foo.dl.sourceforge.net/sourceforge/foozip/foozip_1.0.tar.bz2",
@@ -67,8 +69,11 @@ describe RuboCop::Cop::FormulaAudit::Urls do
"col" => 2,
}, {
"url" => "http://http.debian.net/debian/dists/foo/",
- "msg" => "Please use a secure mirror for Debian URLs.\nWe recommend:\n"\
- " https://mirrors.ocf.berkeley.edu/debian/dists/foo/\n",
+ "msg" => <<-EOS.undent,
+ Please use a secure mirror for Debian URLs.
+ We recommend:
+ https://mirrors.ocf.berkeley.edu/debian/dists/foo/
+ EOS
"col" => 2,
}, {
"url" => "http://foo.googlecode.com/files/foo-1.0.zip",
@@ -96,8 +101,12 @@ describe RuboCop::Cop::FormulaAudit::Urls do
"col" => 2,
}, {
"url" => "https://codeload.github.com/foo/bar/tar.gz/v0.1.1",
- "msg" => "Use GitHub archive URLs:\n https://github.com/foo/bar/archive/v0.1.1.tar.gz\n"\
- "Rather than codeload:\n https://codeload.github.com/foo/bar/tar.gz/v0.1.1\n",
+ "msg" => <<-EOS.undent,
+ Use GitHub archive URLs:
+ https://github.com/foo/bar/archive/v0.1.1.tar.gz
+ Rather than codeload:
+ https://codeload.github.com/foo/bar/tar.gz/v0.1.1
+ EOS
"col" => 2,
}, {
"url" => "https://central.maven.org/maven2/com/bar/foo/1.1/foo-1.1.jar",
@@ -117,7 +126,7 @@ describe RuboCop::Cop::FormulaAudit::Urls do
column: formula["col"],
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expect_offense(expected, actual)
@@ -151,7 +160,7 @@ describe RuboCop::Cop::FormulaAudit::Urls do
column: formula["col"],
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expect_offense(expected, actual)
@@ -174,7 +183,7 @@ describe RuboCop::Cop::FormulaAudit::Urls do
column: 2,
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expect_offense(expected, actual)
@@ -213,13 +222,13 @@ describe RuboCop::Cop::FormulaAuditStrict::PyPiUrls do
column: formula["col"],
source: source }]
- inspect_source(cop, source)
+ inspect_source(source)
# Check for expected offenses
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expect_offense(expected, actual)
end
# Check for expected auto corrected source
- new_source = autocorrect_source(cop, source)
+ new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
diff --git a/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.yosemite.bottle.tar.gz b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.yosemite.bottle.tar.gz
index d88838a94..62ea6c264 100644
--- a/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.yosemite.bottle.tar.gz
+++ b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.yosemite.bottle.tar.gz
Binary files differ
diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-conflicts-with.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-conflicts-with.rb
index ab3631743..13d1fc4fc 100644
--- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-conflicts-with.rb
+++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-conflicts-with.rb
@@ -5,7 +5,7 @@ cask 'with-conflicts-with' do
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
homepage 'http://example.com/with-conflicts-with'
- conflicts_with formula: 'unar'
+ conflicts_with cask: 'local-caffeine'
app 'Caffeine.app'
end
diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-languages.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-languages.rb
new file mode 100644
index 000000000..90ff63846
--- /dev/null
+++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-languages.rb
@@ -0,0 +1,18 @@
+cask 'with-languages' do
+ version '1.2.3'
+
+ language "zh" do
+ sha256 "abc123"
+ "zh-CN"
+ end
+
+ language "en-US", default: true do
+ sha256 "xyz789"
+ "en-US"
+ end
+
+ url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
+ homepage 'http://example.com/local-caffeine'
+
+ app 'Caffeine.app'
+end
diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/without-languages.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/without-languages.rb
new file mode 100644
index 000000000..4c0ce955a
--- /dev/null
+++ b/Library/Homebrew/test/support/fixtures/cask/Casks/without-languages.rb
@@ -0,0 +1,9 @@
+cask 'without-languages' do
+ version '1.2.3'
+ sha256 '67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94'
+
+ url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
+ homepage 'http://example.com/local-caffeine'
+
+ app 'Caffeine.app'
+end
diff --git a/Library/Homebrew/test/support/fixtures/testball_bottle.rb b/Library/Homebrew/test/support/fixtures/testball_bottle.rb
index 9453255e6..5a6be7c5f 100644
--- a/Library/Homebrew/test/support/fixtures/testball_bottle.rb
+++ b/Library/Homebrew/test/support/fixtures/testball_bottle.rb
@@ -6,7 +6,7 @@ class TestballBottle < Formula
stable.bottle do
cellar :any_skip_relocation
root_url "file://#{TEST_FIXTURE_DIR}/bottles"
- sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => Utils::Bottles.tag
+ sha256 "d48bbbe583dcfbfa608579724fc6f0328b3cd316935c6ea22f134610aaf2952f" => Utils::Bottles.tag
end
cxxstdlib_check :skip
end
diff --git a/Library/Homebrew/test/support/fixtures/third-party/Casks/third-party-cask.rb b/Library/Homebrew/test/support/fixtures/third-party/Casks/third-party-cask.rb
new file mode 100644
index 000000000..d7add0522
--- /dev/null
+++ b/Library/Homebrew/test/support/fixtures/third-party/Casks/third-party-cask.rb
@@ -0,0 +1,9 @@
+cask 'third-party-cask' do
+ version '1.2.3'
+ sha256 '8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b'
+
+ url 'http://example.com/ThirdParty.dmg'
+ homepage 'http://example.com/'
+
+ app 'ThirdParty.app'
+end
diff --git a/Library/Homebrew/test/support/helper/fixtures.rb b/Library/Homebrew/test/support/helper/fixtures.rb
index 716fe2008..460fb4aef 100644
--- a/Library/Homebrew/test/support/helper/fixtures.rb
+++ b/Library/Homebrew/test/support/helper/fixtures.rb
@@ -8,6 +8,10 @@ module Test
def bundle_path(name)
Pathname.new("#{TEST_FIXTURE_DIR}/mach/#{name}.bundle")
end
+
+ def cask_path(name)
+ Pathname.new("#{TEST_FIXTURE_DIR}/cask/Casks/#{name}.rb")
+ end
end
end
end
diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
index c51d339a7..fc83149d0 100644
--- a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
+++ b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
@@ -18,6 +18,7 @@ HOMEBREW_CASK_DIRS = [
RSpec.shared_context "Homebrew-Cask" do
around(:each) do |example|
+ third_party_tap = Tap.fetch("third-party", "tap")
begin
dirs = HOMEBREW_CASK_DIRS.map do |dir|
Pathname.new(TEST_TMPDIR).join("cask-#{dir}").tap do |path|
@@ -31,11 +32,18 @@ RSpec.shared_context "Homebrew-Cask" do
FileUtils.ln_sf TEST_FIXTURE_DIR.join("cask"), tap.path
end
+ third_party_tap.tap do |tap|
+ FileUtils.mkdir_p tap.path.dirname
+ FileUtils.ln_sf TEST_FIXTURE_DIR.join("third-party"), tap.path
+ end
+
example.run
ensure
FileUtils.rm_rf dirs
Hbc.default_tap.path.unlink
FileUtils.rm_rf Hbc.default_tap.path.parent
+ third_party_tap.path.unlink
+ FileUtils.rm_rf third_party_tap.path.parent
end
end
end
diff --git a/Library/Homebrew/test/utils/analytics_spec.rb b/Library/Homebrew/test/utils/analytics_spec.rb
new file mode 100644
index 000000000..bb6cda0b1
--- /dev/null
+++ b/Library/Homebrew/test/utils/analytics_spec.rb
@@ -0,0 +1,88 @@
+require "utils/analytics"
+require "formula_installer"
+
+describe Utils::Analytics do
+ describe "::os_prefix_ci" do
+ context "when anonymous_os_prefix_ci is not set" do
+ before(:each) do
+ described_class.clear_anonymous_os_prefix_ci_cache
+ end
+
+ it "returns OS_VERSION and prefix when HOMEBREW_PREFIX is not /usr/local" do
+ stub_const("HOMEBREW_PREFIX", "blah")
+ expect(described_class.os_prefix_ci).to include("#{OS_VERSION}, non-/usr/local")
+ end
+
+ it "includes CI when ENV['CI'] is set" do
+ ENV["CI"] = "true"
+ expect(described_class.os_prefix_ci).to include("CI")
+ end
+
+ it "does not include prefix when HOMEBREW_PREFIX is /usr/local" do
+ stub_const("HOMEBREW_PREFIX", "/usr/local")
+ expect(described_class.os_prefix_ci).not_to include("non-/usr/local")
+ end
+ end
+ end
+
+ describe "::report_event" do
+ let(:f) { formula { url "foo-1.0" } }
+ let(:options) { FormulaInstaller.new(f).display_options(f) }
+ let(:action) { "#{f.full_name} #{options}".strip }
+
+ context "when ENV vars is set" do
+ it "returns nil when HOMEBREW_NO_ANALYTICS is true" do
+ ENV["HOMEBREW_NO_ANALYTICS"] = "true"
+ expect(described_class.report_event("install", action)).to be_nil
+ end
+
+ it "returns nil when HOMEBREW_NO_ANALYTICS_THIS_RUN is true" do
+ ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "true"
+ expect(described_class.report_event("install", action)).to be_nil
+ end
+
+ it "returns nil when HOMEBREW_ANALYTICS_DEBUG is true" do
+ ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
+ ENV.delete("HOMEBREW_NO_ANALYTICS")
+ ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
+ expect(described_class.report_event("install", action)).to be_nil
+ end
+ end
+ end
+
+ describe "::report_build_error" do
+ context "when tap is installed" do
+ let(:err) { BuildError.new(f, "badprg", %w[arg1 arg2], {}) }
+ let(:f) { formula { url "foo-1.0" } }
+
+ it "reports event if BuildError raised for a formula with a public remote repository" do
+ allow_any_instance_of(Tap).to receive(:custom_remote?).and_return(false)
+ expect(described_class).to respond_to(:report_event)
+ described_class.report_build_error(err)
+ end
+
+ it "does not report event if BuildError raised for a formula with a private remote repository" do
+ expect(described_class.report_build_error(err)).to be_nil
+ end
+ end
+
+ context "when formula does not have a tap" do
+ let(:err) { BuildError.new(f, "badprg", %w[arg1 arg2], {}) }
+ let(:f) { double(Formula, name: "foo", path: "blah", tap: nil) }
+
+ it "does not report event if BuildError is raised" do
+ expect(described_class.report_build_error(err)).to be_nil
+ end
+ end
+
+ context "when tap for a formula is not installed" do
+ let(:err) { BuildError.new(f, "badprg", %w[arg1 arg2], {}) }
+ let(:f) { double(Formula, name: "foo", path: "blah", tap: CoreTap.instance) }
+
+ it "does not report event if BuildError is raised" do
+ allow_any_instance_of(Pathname).to receive(:directory?).and_return(false)
+ expect(described_class.report_build_error(err)).to be_nil
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/utils/git_spec.rb b/Library/Homebrew/test/utils/git_spec.rb
new file mode 100644
index 000000000..48fc1338e
--- /dev/null
+++ b/Library/Homebrew/test/utils/git_spec.rb
@@ -0,0 +1,150 @@
+require "utils/git"
+
+describe Git do
+ before(:each) do
+ git = HOMEBREW_SHIMS_PATH/"scm/git"
+
+ HOMEBREW_CACHE.cd do
+ system git, "init"
+
+ File.open(file, "w") { |f| f.write("blah") }
+ system git, "add", HOMEBREW_CACHE/file
+ system git, "commit", "-m", "'File added'"
+ @h1 = `git rev-parse HEAD`
+
+ File.open(file, "w") { |f| f.write("brew") }
+ system git, "add", HOMEBREW_CACHE/file
+ system git, "commit", "-m", "'written to File'"
+ @h2 = `git rev-parse HEAD`
+ end
+ end
+
+ let(:file) { "blah.rb" }
+ let(:hash1) { @h1[0..6] }
+ let(:hash2) { @h2[0..6] }
+
+ describe "#last_revision_commit_of_file" do
+ it "gives last revision commit when before_commit is nil" do
+ expect(
+ described_class.last_revision_commit_of_file(HOMEBREW_CACHE, file),
+ ).to eq(hash1)
+ end
+
+ it "gives revision commit based on before_commit when it is not nil" do
+ expect(
+ described_class.last_revision_commit_of_file(HOMEBREW_CACHE,
+ file,
+ before_commit: hash2),
+ ).to eq(hash2)
+ end
+ end
+
+ describe "#last_revision_of_file" do
+ it "returns last revision of file" do
+ expect(
+ described_class.last_revision_of_file(HOMEBREW_CACHE,
+ HOMEBREW_CACHE/file),
+ ).to eq("blah")
+ end
+
+ it "returns last revision of file based on before_commit" do
+ expect(
+ described_class.last_revision_of_file(HOMEBREW_CACHE, HOMEBREW_CACHE/file,
+ before_commit: "0..3"),
+ ).to eq("brew")
+ end
+ end
+end
+
+describe Utils do
+ before(:each) do
+ described_class.clear_git_available_cache
+ end
+
+ describe "::git_available?" do
+ it "returns true if git --version command succeeds" do
+ expect(described_class.git_available?).to be_truthy
+ end
+
+ it "returns false if git --version command does not succeed" do
+ stub_const("HOMEBREW_SHIMS_PATH", HOMEBREW_PREFIX/"bin/shim")
+ expect(described_class.git_available?).to be_falsey
+ end
+ end
+
+ describe "::git_path" do
+ it "returns nil when git is not available" do
+ stub_const("HOMEBREW_SHIMS_PATH", HOMEBREW_PREFIX/"bin/shim")
+ expect(described_class.git_path).to eq(nil)
+ end
+
+ it "returns path of git when git is available" do
+ expect(described_class.git_path).to end_with("git")
+ end
+ end
+
+ describe "::git_version" do
+ it "returns nil when git is not available" do
+ stub_const("HOMEBREW_SHIMS_PATH", HOMEBREW_PREFIX/"bin/shim")
+ expect(described_class.git_path).to eq(nil)
+ end
+
+ it "returns version of git when git is available" do
+ expect(described_class.git_version).not_to be_nil
+ end
+ end
+
+ describe "::ensure_git_installed!" do
+ it "returns nil if git already available" do
+ expect(described_class.ensure_git_installed!).to be_nil
+ end
+
+ context "when git is not already available" do
+ before do
+ stub_const("HOMEBREW_SHIMS_PATH", HOMEBREW_PREFIX/"bin/shim")
+ end
+
+ it "can't install brewed git if homebrew/core is unavailable" do
+ allow_any_instance_of(Pathname).to receive(:directory?).and_return(false)
+ expect { described_class.ensure_git_installed! }.to raise_error("Git is unavailable")
+ end
+
+ it "raises error if can't install git" do
+ stub_const("HOMEBREW_BREW_FILE", HOMEBREW_PREFIX/"bin/brew")
+ expect { described_class.ensure_git_installed! }.to raise_error("Git is unavailable")
+ end
+
+ it "installs git" do
+ allow(Homebrew).to receive(:_system).with(any_args).and_return(true)
+ described_class.ensure_git_installed!
+ end
+ end
+ end
+
+ describe "::git_remote_exists" do
+ it "returns true when git is not available" do
+ stub_const("HOMEBREW_SHIMS_PATH", HOMEBREW_PREFIX/"bin/shim")
+ expect(described_class.git_remote_exists("blah")).to be_truthy
+ end
+
+ context "when git is available" do
+ it "returns true when git remote exists", :needs_network do
+ git = HOMEBREW_SHIMS_PATH/"scm/git"
+ url = "https://github.com/Homebrew/homebrew.github.io"
+ repo = HOMEBREW_CACHE/"hey"
+ repo.mkpath
+
+ repo.cd do
+ system git, "init"
+ system git, "remote", "add", "origin", url
+ end
+
+ expect(described_class.git_remote_exists(url)).to be_truthy
+ end
+
+ it "returns false when git remote does not exist" do
+ expect(described_class.git_remote_exists("blah")).to be_falsey
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/utils/github_spec.rb b/Library/Homebrew/test/utils/github_spec.rb
index 9b539262f..a132894f9 100644
--- a/Library/Homebrew/test/utils/github_spec.rb
+++ b/Library/Homebrew/test/utils/github_spec.rb
@@ -2,12 +2,38 @@ require "utils/github"
describe GitHub do
describe "::search_code", :needs_network do
- it "searches code" do
- results = subject.search_code("repo:Homebrew/brew", "path:/", "filename:readme", "language:markdown")
+ it "queries GitHub code with the passed parameters" do
+ results = subject.search_code(repo: "Homebrew/brew", path: "/",
+ filename: "readme", language: "markdown")
expect(results.count).to eq(1)
expect(results.first["name"]).to eq("README.md")
expect(results.first["path"]).to eq("README.md")
end
end
+
+ describe "::query_string" do
+ it "builds a query with the given hash parameters formatted as key:value" do
+ query = subject.query_string(user: "Homebrew", repo: "brew")
+ expect(query).to eq("q=user%3AHomebrew+repo%3Abrew&per_page=100")
+ end
+
+ it "adds a variable number of top-level string parameters to the query when provided" do
+ query = subject.query_string("value1", "value2", user: "Homebrew")
+ expect(query).to eq("q=value1+value2+user%3AHomebrew&per_page=100")
+ end
+
+ it "turns array values into multiple key:value parameters" do
+ query = subject.query_string(user: ["Homebrew", "caskroom"])
+ expect(query).to eq("q=user%3AHomebrew+user%3Acaskroom&per_page=100")
+ end
+ end
+
+ describe "::search_issues", :needs_network do
+ it "queries GitHub issues with the passed parameters" do
+ results = subject.search_issues("brew search", repo: "Homebrew/brew", author: "avetamine", is: "closed")
+ expect(results).not_to be_empty
+ expect(results.last["title"]).to eq("brew search : 422 Unprocessable Entity")
+ end
+ end
end
diff --git a/Library/Homebrew/test/utils/svn_spec.rb b/Library/Homebrew/test/utils/svn_spec.rb
new file mode 100644
index 000000000..4edb365a0
--- /dev/null
+++ b/Library/Homebrew/test/utils/svn_spec.rb
@@ -0,0 +1,39 @@
+require "utils/svn"
+
+describe Utils do
+ describe "#self.svn_available?" do
+ before(:each) do
+ described_class.clear_svn_version_cache
+ end
+
+ it "returns svn version if svn available" do
+ expect(described_class.svn_available?).to be_truthy
+ end
+ end
+
+ describe "#self.svn_remote_exists" do
+ it "returns true when svn is not available" do
+ allow(Utils).to receive(:svn_available?).and_return(false)
+ expect(described_class.svn_remote_exists("blah")).to be_truthy
+ end
+
+ context "when svn is available" do
+ before do
+ allow(Utils).to receive(:svn_available?).and_return(true)
+ end
+
+ it "returns false when remote does not exist" do
+ expect(described_class.svn_remote_exists(HOMEBREW_CACHE/"install")).to be_falsey
+ end
+
+ it "returns true when remote exists", :needs_network do
+ remote = "http://github.com/Homebrew/install"
+ svn = HOMEBREW_SHIMS_PATH/"scm/svn"
+
+ HOMEBREW_CACHE.cd { system svn, "checkout", remote }
+
+ expect(described_class.svn_remote_exists(HOMEBREW_CACHE/"install")).to be_truthy
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/utils_spec.rb b/Library/Homebrew/test/utils_spec.rb
index 37bd83c4f..3b5355b15 100644
--- a/Library/Homebrew/test/utils_spec.rb
+++ b/Library/Homebrew/test/utils_spec.rb
@@ -296,4 +296,33 @@ describe "globally-scoped helper methods" do
expect(ENV["PATH"]).not_to eq("/bin")
end
end
+
+ describe "#tap_and_name_comparison" do
+ describe "both strings are only names" do
+ it "alphabetizes the strings" do
+ expect(%w[a b].sort(&tap_and_name_comparison)).to eq(%w[a b])
+ expect(%w[b a].sort(&tap_and_name_comparison)).to eq(%w[a b])
+ end
+ end
+
+ describe "both strings include tap" do
+ it "alphabetizes the strings" do
+ expect(%w[a/z/z b/z/z].sort(&tap_and_name_comparison)).to eq(%w[a/z/z b/z/z])
+ expect(%w[b/z/z a/z/z].sort(&tap_and_name_comparison)).to eq(%w[a/z/z b/z/z])
+
+ expect(%w[z/a/z z/b/z].sort(&tap_and_name_comparison)).to eq(%w[z/a/z z/b/z])
+ expect(%w[z/b/z z/a/z].sort(&tap_and_name_comparison)).to eq(%w[z/a/z z/b/z])
+
+ expect(%w[z/z/a z/z/b].sort(&tap_and_name_comparison)).to eq(%w[z/z/a z/z/b])
+ expect(%w[z/z/b z/z/a].sort(&tap_and_name_comparison)).to eq(%w[z/z/a z/z/b])
+ end
+ end
+
+ describe "only one string includes tap" do
+ it "prefers the string without tap" do
+ expect(%w[a/z/z z].sort(&tap_and_name_comparison)).to eq(%w[z a/z/z])
+ expect(%w[z a/z/z].sort(&tap_and_name_comparison)).to eq(%w[z a/z/z])
+ end
+ end
+ end
end
diff --git a/Library/Homebrew/test/version_spec.rb b/Library/Homebrew/test/version_spec.rb
index cee57e935..d0393afa6 100644
--- a/Library/Homebrew/test/version_spec.rb
+++ b/Library/Homebrew/test/version_spec.rb
@@ -241,8 +241,18 @@ describe Version do
describe "::detect" do
matcher :be_detected_from do |url, specs = {}|
- match do |version|
- Version.detect(url, specs) == version
+ detected = Version.detect(url, specs)
+
+ match do |expected|
+ detected == expected
+ end
+
+ failure_message do |expected|
+ message = <<-EOS
+ expected: %s
+ detected: %s
+ EOS
+ format(message, expected, detected)
end
end
@@ -639,6 +649,11 @@ describe Version do
.to be_detected_from("ftp://gcc.gnu.org/pub/gcc/snapshots/6-20151227/gcc-6-20151227.tar.bz2")
end
+ specify "semver in middle of URL" do
+ expect(Version.create("7.1.10"))
+ .to be_detected_from("https://php.net/get/php-7.1.10.tar.gz/from/this/mirror")
+ end
+
specify "from URL" do
expect(Version.create("1.2.3"))
.to be_detected_from("http://github.com/foo/bar.git", tag: "v1.2.3")
diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb
index e3137ac49..237ffa74e 100644
--- a/Library/Homebrew/utils.rb
+++ b/Library/Homebrew/utils.rb
@@ -102,7 +102,7 @@ def odeprecated(method, replacement = nil, disable: false, disable_on: nil, call
if ARGV.homebrew_developer? || disable ||
Homebrew.raise_deprecation_exceptions?
raise MethodDeprecatedError, message
- else
+ elsif !Homebrew.auditing?
opoo "#{message}\n"
end
end
@@ -229,10 +229,9 @@ module Homebrew
EOS
end
- # Hash of Module => Set(method_names)
- @injected_dump_stat_modules = {}
-
+ # rubocop:disable Style/GlobalVars
def inject_dump_stats!(the_module, pattern)
+ @injected_dump_stat_modules ||= {}
@injected_dump_stat_modules[the_module] ||= []
injected_methods = @injected_dump_stat_modules[the_module]
the_module.module_eval do
@@ -260,11 +259,12 @@ module Homebrew
end
end
end
+ # rubocop:enable Style/GlobalVars
end
def with_system_path
old_path = ENV["PATH"]
- ENV["PATH"] = "/usr/bin:/bin"
+ ENV["PATH"] = PATH.new("/usr/bin", "/bin")
yield
ensure
ENV["PATH"] = old_path
@@ -560,3 +560,15 @@ end
def shell_profile
Utils::Shell.profile
end
+
+def tap_and_name_comparison
+ proc do |a, b|
+ if a.include?("/") && !b.include?("/")
+ 1
+ elsif !a.include?("/") && b.include?("/")
+ -1
+ else
+ a <=> b
+ end
+ end
+end
diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb
index a89995ba9..9766c14db 100644
--- a/Library/Homebrew/utils/analytics.rb
+++ b/Library/Homebrew/utils/analytics.rb
@@ -3,6 +3,11 @@ require "erb"
module Utils
module Analytics
class << self
+ def clear_anonymous_os_prefix_ci_cache
+ return unless instance_variable_defined?(:@anonymous_os_prefix_ci)
+ remove_instance_variable(:@anonymous_os_prefix_ci)
+ end
+
def os_prefix_ci
@anonymous_os_prefix_ci ||= begin
os = OS_VERSION
diff --git a/Library/Homebrew/utils/bottles.rb b/Library/Homebrew/utils/bottles.rb
index 927963bc1..66b5fb640 100644
--- a/Library/Homebrew/utils/bottles.rb
+++ b/Library/Homebrew/utils/bottles.rb
@@ -29,9 +29,11 @@ module Utils
end
def receipt_path(bottle_file)
- Utils.popen_read("tar", "-tzf", bottle_file).lines.map(&:chomp).find do |line|
+ path = Utils.popen_read("tar", "-tzf", bottle_file).lines.map(&:chomp).find do |line|
line =~ %r{.+/.+/INSTALL_RECEIPT.json}
end
+ raise "This bottle does not contain the file INSTALL_RECEIPT.json: #{bottle_file}" unless path
+ path
end
def resolve_formula_names(bottle_file)
@@ -52,6 +54,15 @@ module Utils
def resolve_version(bottle_file)
PkgVersion.parse receipt_path(bottle_file).split("/")[1]
end
+
+ def formula_contents(bottle_file,
+ name: resolve_formula_names(bottle_file)[0])
+ bottle_version = resolve_version bottle_file
+ formula_path = "#{name}/#{bottle_version}/.brew/#{name}.rb"
+ contents = Utils.popen_read "tar", "-xOzf", bottle_file, formula_path
+ raise BottleFormulaUnavailableError.new(bottle_file, formula_path) unless $CHILD_STATUS.success?
+ contents
+ end
end
class Bintray
diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb
index 5a40ae846..7807d2034 100644
--- a/Library/Homebrew/utils/curl.rb
+++ b/Library/Homebrew/utils/curl.rb
@@ -1,42 +1,57 @@
require "pathname"
require "open3"
-def curl_args(options = {})
+def curl_executable
curl = Pathname.new ENV["HOMEBREW_CURL"]
curl = Pathname.new "/usr/bin/curl" unless curl.exist?
- raise "#{curl} is not executable" unless curl.exist? && curl.executable?
+ return curl if curl.executable?
+ raise "#{curl} is not executable"
+end
+def curl_args(*extra_args, show_output: false, user_agent: :default)
args = [
- curl.to_s,
- "--remote-time",
- "--location",
+ curl_executable.to_s,
+ "--show-error",
]
- case options[:user_agent]
- when :browser
- args << "--user-agent" << HOMEBREW_USER_AGENT_FAKE_SAFARI
+ args << "--user-agent" << case user_agent
+ when :browser, :fake
+ HOMEBREW_USER_AGENT_FAKE_SAFARI
+ when :default
+ HOMEBREW_USER_AGENT_CURL
else
- args << "--user-agent" << HOMEBREW_USER_AGENT_CURL
+ user_agent
end
- unless options[:show_output]
+ unless show_output
+ args << "--fail"
args << "--progress-bar" unless ARGV.verbose?
args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"]
- args << "--fail"
args << "--silent" if !$stdout.tty? || ENV["TRAVIS"]
end
- args += options[:extra_args] if options[:extra_args]
- args
+ args + extra_args
end
def curl(*args)
- safe_system(*curl_args(extra_args: args))
+ safe_system(*curl_args(*args))
end
-def curl_output(*args)
- curl_args = curl_args(extra_args: args, show_output: true)
- Open3.popen3(*curl_args) do |_, stdout, stderr, wait_thread|
- [stdout.read, stderr.read, wait_thread.value]
+def curl_download(*args, to: nil, continue_at: "-", **options)
+ had_incomplete_download ||= File.exist?(to)
+ curl("--location", "--remote-time", "--continue-at", continue_at.to_s, "--output", to, *args, **options)
+rescue ErrorDuringExecution
+ # `curl` error 33: HTTP server doesn't seem to support byte ranges. Cannot resume.
+ # HTTP status 416: Requested range not satisfiable
+ if ($CHILD_STATUS.exitstatus == 33 || had_incomplete_download) && continue_at == "-"
+ continue_at = 0
+ had_incomplete_download = false
+ retry
end
+
+ raise
+end
+
+def curl_output(*args, **options)
+ Open3.capture3(*curl_args(*args, show_output: true, **options))
end
diff --git a/Library/Homebrew/utils/fork.rb b/Library/Homebrew/utils/fork.rb
index 92f5bf899..57ddbfae2 100644
--- a/Library/Homebrew/utils/fork.rb
+++ b/Library/Homebrew/utils/fork.rb
@@ -14,7 +14,7 @@ module Utils
read.close
write.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
yield
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
Marshal.dump(e, write)
write.close
exit!
@@ -26,8 +26,11 @@ module Utils
ignore_interrupts(:quietly) do # the child will receive the interrupt and marshal it back
begin
socket = server.accept_nonblock
+ # rubocop:disable Lint/ShadowedException
+ # FIXME: https://github.com/bbatsov/rubocop/issues/4843
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
retry unless Process.waitpid(pid, Process::WNOHANG)
+ # rubocop:enable Lint/ShadowedException
else
socket.send_io(write)
socket.close
@@ -36,9 +39,9 @@ module Utils
data = read.read
read.close
Process.wait(pid) unless socket.nil?
- raise Marshal.load(data) unless data.nil? || data.empty?
+ raise Marshal.load(data) unless data.nil? || data.empty? # rubocop:disable Security/MarshalLoad
raise Interrupt if $CHILD_STATUS.exitstatus == 130
- raise "Suspicious failure" unless $CHILD_STATUS.success?
+ raise "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success?
end
end
end
diff --git a/Library/Homebrew/utils/git.rb b/Library/Homebrew/utils/git.rb
index 43d93b64e..f1113af66 100644
--- a/Library/Homebrew/utils/git.rb
+++ b/Library/Homebrew/utils/git.rb
@@ -16,8 +16,7 @@ module Git
def last_revision_of_file(repo, file, before_commit: nil)
relative_file = Pathname(file).relative_path_from(repo)
- commit_hash = last_revision_commit_of_file(repo, file, before_commit: before_commit)
-
+ commit_hash = last_revision_commit_of_file(repo, relative_file, before_commit: before_commit)
out, = Open3.capture3(
HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
"show", "#{commit_hash}:#{relative_file}"
@@ -28,8 +27,7 @@ end
module Utils
def self.git_available?
- return @git if instance_variable_defined?(:@git)
- @git = quiet_system HOMEBREW_SHIMS_PATH/"scm/git", "--version"
+ @git ||= quiet_system HOMEBREW_SHIMS_PATH/"scm/git", "--version"
end
def self.git_path
@@ -50,21 +48,20 @@ module Utils
return if git_available?
# we cannot install brewed git if homebrew/core is unavailable.
- raise "Git is unavailable" unless CoreTap.instance.installed?
-
- begin
- oh1 "Installing git"
- safe_system HOMEBREW_BREW_FILE, "install", "git"
- rescue
- raise "Git is unavailable"
+ if CoreTap.instance.installed?
+ begin
+ oh1 "Installing git"
+ safe_system HOMEBREW_BREW_FILE, "install", "git"
+ rescue
+ raise "Git is unavailable"
+ end
end
- clear_git_available_cache
raise "Git is unavailable" unless git_available?
end
def self.clear_git_available_cache
- remove_instance_variable(:@git) if instance_variable_defined?(:@git)
+ @git = nil
@git_path = nil
@git_version = nil
end
diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb
index 1a781cee6..df0811e95 100644
--- a/Library/Homebrew/utils/github.rb
+++ b/Library/Homebrew/utils/github.rb
@@ -86,15 +86,9 @@ module GitHub
def api_credentials_type
token, username = api_credentials
- if token && !token.empty?
- if username && !username.empty?
- :keychain
- else
- :environment
- end
- else
- :none
- end
+ return :none if !token || token.empty?
+ return :keychain if !username || username.empty?
+ :environment
end
def api_credentials_error_message(response_headers, needed_scopes)
@@ -133,7 +127,7 @@ module GitHub
def open(url, data: nil, scopes: [].freeze)
# This is a no-op if the user is opting out of using the GitHub API.
- return if ENV["HOMEBREW_NO_GITHUB_API"]
+ return block_given? ? yield({}) : {} if ENV["HOMEBREW_NO_GITHUB_API"]
args = %W[--header application/vnd.github.v3+json --write-out \n%{http_code}]
args += curl_args
@@ -166,7 +160,7 @@ module GitHub
args += ["--dump-header", headers_tmpfile.path]
- output, errors, status = curl_output(url.to_s, *args)
+ output, errors, status = curl_output(url.to_s, "--location", *args)
output, _, http_code = output.rpartition("\n")
output, _, http_code = output.rpartition("\n") if http_code == "000"
headers = headers_tmpfile.read
@@ -227,72 +221,60 @@ module GitHub
end
end
- def issues_matching(query, qualifiers = {})
- uri = URI.parse("#{API_URL}/search/issues")
- uri.query = build_query_string(query, qualifiers)
- open(uri) { |json| json["items"] }
+ def search_issues(query, **qualifiers)
+ search("issues", query, **qualifiers)
end
def repository(user, repo)
- open(URI.parse("#{API_URL}/repos/#{user}/#{repo}"))
- end
-
- def search_code(*params)
- uri = URI.parse("#{API_URL}/search/code")
- uri.query = "q=#{uri_escape(params.join(" "))}"
- open(uri) { |json| json["items"] }
+ open(url_to("repos", user, repo))
end
- def build_query_string(query, qualifiers)
- s = "q=#{uri_escape(query)}+"
- s << build_search_qualifier_string(qualifiers)
- s << "&per_page=100"
- end
-
- def build_search_qualifier_string(qualifiers)
- {
- repo: "Homebrew/homebrew-core",
- in: "title",
- }.update(qualifiers).map do |qualifier, value|
- "#{qualifier}:#{value}"
- end.join("+")
- end
-
- def uri_escape(query)
- if URI.respond_to?(:encode_www_form_component)
- URI.encode_www_form_component(query)
- else
- require "erb"
- ERB::Util.url_encode(query)
- end
+ def search_code(**qualifiers)
+ search("code", **qualifiers)
end
def issues_for_formula(name, options = {})
tap = options[:tap] || CoreTap.instance
- issues_matching(name, state: "open", repo: "#{tap.user}/homebrew-#{tap.repo}")
+ search_issues(name, state: "open", repo: "#{tap.user}/homebrew-#{tap.repo}")
end
def print_pull_requests_matching(query)
- return [] if ENV["HOMEBREW_NO_GITHUB_API"]
-
- open_or_closed_prs = issues_matching(query, type: "pr")
+ open_or_closed_prs = search_issues(query, type: "pr", user: "Homebrew")
open_prs = open_or_closed_prs.select { |i| i["state"] == "open" }
- if !open_prs.empty?
+ prs = if !open_prs.empty?
puts "Open pull requests:"
- prs = open_prs
- elsif !open_or_closed_prs.empty?
- puts "Closed pull requests:"
- prs = open_or_closed_prs
+ open_prs
else
- return
+ puts "Closed pull requests:" unless open_or_closed_prs.empty?
+ open_or_closed_prs
end
prs.each { |i| puts "#{i["title"]} (#{i["html_url"]})" }
end
def private_repo?(full_name)
- uri = URI.parse("#{API_URL}/repos/#{full_name}")
+ uri = url_to "repos", full_name
open(uri) { |json| json["private"] }
end
+
+ def query_string(*main_params, **qualifiers)
+ params = main_params
+
+ params += qualifiers.flat_map do |key, value|
+ Array(value).map { |v| "#{key}:#{v}" }
+ end
+
+ "q=#{URI.encode_www_form_component(params.join(" "))}&per_page=100"
+ end
+
+ def url_to(*subroutes)
+ URI.parse([API_URL, *subroutes].join("/"))
+ end
+
+ def search(entity, *queries, **qualifiers)
+ uri = url_to "search", entity
+ uri.query = query_string(*queries, **qualifiers)
+ open(uri) { |json| json.fetch("items", []) }
+ end
end
diff --git a/Library/Homebrew/utils/popen.rb b/Library/Homebrew/utils/popen.rb
index 4e03711a1..2fa3ade46 100644
--- a/Library/Homebrew/utils/popen.rb
+++ b/Library/Homebrew/utils/popen.rb
@@ -1,20 +1,20 @@
module Utils
- def self.popen_read(*args, &block)
- popen(args, "rb", &block)
+ def self.popen_read(*args, **options, &block)
+ popen(args, "rb", options, &block)
end
- def self.popen_write(*args, &block)
- popen(args, "wb", &block)
+ def self.popen_write(*args, **options, &block)
+ popen(args, "wb", options, &block)
end
- def self.popen(args, mode)
+ def self.popen(args, mode, options = {})
IO.popen("-", mode) do |pipe|
if pipe
return pipe.read unless block_given?
yield pipe
else
- $stderr.reopen("/dev/null", "w")
- exec(*args)
+ options[:err] ||= :close unless ENV["HOMEBREW_STDERR"]
+ exec(*args, options)
end
end
end
diff --git a/Library/Homebrew/utils/ruby.sh b/Library/Homebrew/utils/ruby.sh
index 6945c068b..9a3ab2e81 100644
--- a/Library/Homebrew/utils/ruby.sh
+++ b/Library/Homebrew/utils/ruby.sh
@@ -2,7 +2,8 @@ setup-ruby-path() {
local vendor_dir
local vendor_ruby_current_version
local vendor_ruby_path
- local ruby_version_major
+ local ruby_old_version
+ local minimum_ruby_version="2.3.3"
vendor_dir="$HOMEBREW_LIBRARY/Homebrew/vendor"
vendor_ruby_current_version="$vendor_dir/portable-ruby/current"
@@ -21,7 +22,7 @@ setup-ruby-path() {
if [[ $(readlink "$vendor_ruby_current_version") != "$(<"$vendor_dir/portable-ruby-version")" ]]
then
- if ! brew vendor-install ruby --quiet
+ if ! brew vendor-install ruby
then
onoe "Failed to upgrade vendor Ruby."
fi
@@ -36,14 +37,12 @@ setup-ruby-path() {
if [[ -n "$HOMEBREW_RUBY_PATH" ]]
then
- ruby_version_major="$("$HOMEBREW_RUBY_PATH" --version)"
- ruby_version_major="${ruby_version_major#ruby }"
- ruby_version_major="${ruby_version_major%%.*}"
+ ruby_old_version="$("$HOMEBREW_RUBY_PATH" -rrubygems -e "puts Gem::Version.new('$minimum_ruby_version') > Gem::Version.new(RUBY_VERSION)")"
fi
- if [[ "$ruby_version_major" != "2" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" ]]
+ if [[ "$ruby_old_version" == "true" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" ]]
then
- brew vendor-install ruby --quiet
+ brew vendor-install ruby
if [[ ! -x "$vendor_ruby_path" ]]
then
odie "Failed to install vendor Ruby."
diff --git a/Library/Homebrew/utils/shell.rb b/Library/Homebrew/utils/shell.rb
index 5327f6ecf..8c1c5f984 100644
--- a/Library/Homebrew/utils/shell.rb
+++ b/Library/Homebrew/utils/shell.rb
@@ -51,8 +51,6 @@ module Utils
end
end
- private
-
SHELL_PROFILE_MAP = {
bash: "~/.bash_profile",
csh: "~/.cshrc",
@@ -65,8 +63,6 @@ module Utils
UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])}
- module_function
-
def csh_quote(str)
# ruby's implementation of shell_escape
str = str.to_s
diff --git a/Library/Homebrew/utils/svn.rb b/Library/Homebrew/utils/svn.rb
index fb49ac2e9..150b7eee7 100644
--- a/Library/Homebrew/utils/svn.rb
+++ b/Library/Homebrew/utils/svn.rb
@@ -1,4 +1,8 @@
module Utils
+ def self.clear_svn_version_cache
+ remove_instance_variable(:@svn) if instance_variable_defined?(:@svn)
+ end
+
def self.svn_available?
return @svn if instance_variable_defined?(:@svn)
@svn = quiet_system HOMEBREW_SHIMS_PATH/"scm/svn", "--version"
diff --git a/Library/Homebrew/vendor/portable-ruby-version b/Library/Homebrew/vendor/portable-ruby-version
index 633c00da3..0bee604df 100644
--- a/Library/Homebrew/vendor/portable-ruby-version
+++ b/Library/Homebrew/vendor/portable-ruby-version
@@ -1 +1 @@
-2.0.0-p648
+2.3.3
diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb
index b03a4bc33..d43e0c665 100644
--- a/Library/Homebrew/version.rb
+++ b/Library/Homebrew/version.rb
@@ -213,110 +213,6 @@ class Version
end
end
- def initialize(val)
- unless val.respond_to?(:to_str)
- raise TypeError, "Version value must be a string; got a #{val.class} (#{val})"
- end
- @version = val.to_str
- end
-
- def detected_from_url?
- false
- end
-
- def head?
- false
- end
-
- def null?
- false
- end
-
- def <=>(other)
- # Needed to retain API compatibility with older string comparisons
- # for compiler versions, etc.
- other = Version.new(other) if other.is_a? String
- # Used by the *_build_version comparisons, which formerly returned Fixnum
- other = Version.new(other.to_s) if other.is_a? Integer
- return 1 if other.nil?
-
- return unless other.is_a?(Version)
- return 0 if version == other.version
- return 1 if head? && !other.head?
- return -1 if !head? && other.head?
- return 0 if head? && other.head?
-
- ltokens = tokens
- rtokens = other.tokens
- max = max(ltokens.length, rtokens.length)
- l = r = 0
-
- while l < max
- a = ltokens[l] || NULL_TOKEN
- b = rtokens[r] || NULL_TOKEN
-
- if a == b
- l += 1
- r += 1
- next
- elsif a.numeric? && b.numeric?
- return a <=> b
- elsif a.numeric?
- return 1 if a > NULL_TOKEN
- l += 1
- elsif b.numeric?
- return -1 if b > NULL_TOKEN
- r += 1
- else
- return a <=> b
- end
- end
-
- 0
- end
- alias eql? ==
-
- def hash
- version.hash
- end
-
- def to_f
- version.to_f
- end
-
- def to_s
- version.dup
- end
- alias to_str to_s
-
- protected
-
- attr_reader :version
-
- def tokens
- @tokens ||= tokenize
- end
-
- private
-
- def max(a, b)
- (a > b) ? a : b
- end
-
- def tokenize
- version.scan(SCAN_PATTERN).map! do |token|
- case token
- when /\A#{AlphaToken::PATTERN}\z/o then AlphaToken
- when /\A#{BetaToken::PATTERN}\z/o then BetaToken
- when /\A#{RCToken::PATTERN}\z/o then RCToken
- when /\A#{PreToken::PATTERN}\z/o then PreToken
- when /\A#{PatchToken::PATTERN}\z/o then PatchToken
- when /\A#{NumericToken::PATTERN}\z/o then NumericToken
- when /\A#{StringToken::PATTERN}\z/o then StringToken
- end.new(token)
- end
- end
-
def self.parse(spec)
version = _parse(spec)
version.nil? ? NULL : new(version)
@@ -456,6 +352,116 @@ class Version
# e.g. http://www.ijg.org/files/jpegsrc.v8d.tar.gz
m = /\.v(\d+[a-z]?)/.match(stem)
return m.captures.first unless m.nil?
+
+ # e.g. https://secure.php.net/get/php-7.1.10.tar.bz2/from/this/mirror
+ m = /[-.vV]?((?:\d+\.)+\d+(?:[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})?)/.match(spec_s)
+ return m.captures.first unless m.nil?
+ end
+
+ private_class_method :_parse
+
+ def initialize(val)
+ unless val.respond_to?(:to_str)
+ raise TypeError, "Version value must be a string; got a #{val.class} (#{val})"
+ end
+ @version = val.to_str
+ end
+
+ def detected_from_url?
+ false
+ end
+
+ def head?
+ false
+ end
+
+ def null?
+ false
+ end
+
+ def <=>(other)
+ # Needed to retain API compatibility with older string comparisons
+ # for compiler versions, etc.
+ other = Version.new(other) if other.is_a? String
+ # Used by the *_build_version comparisons, which formerly returned Fixnum
+ other = Version.new(other.to_s) if other.is_a? Integer
+ return 1 if other.nil?
+
+ return unless other.is_a?(Version)
+ return 0 if version == other.version
+ return 1 if head? && !other.head?
+ return -1 if !head? && other.head?
+ return 0 if head? && other.head?
+
+ ltokens = tokens
+ rtokens = other.tokens
+ max = max(ltokens.length, rtokens.length)
+ l = r = 0
+
+ while l < max
+ a = ltokens[l] || NULL_TOKEN
+ b = rtokens[r] || NULL_TOKEN
+
+ if a == b
+ l += 1
+ r += 1
+ next
+ elsif a.numeric? && b.numeric?
+ return a <=> b
+ elsif a.numeric?
+ return 1 if a > NULL_TOKEN
+ l += 1
+ elsif b.numeric?
+ return -1 if b > NULL_TOKEN
+ r += 1
+ else
+ return a <=> b
+ end
+ end
+
+ 0
+ end
+ alias eql? ==
+
+ def hash
+ version.hash
+ end
+
+ def to_f
+ version.to_f
+ end
+
+ def to_s
+ version.dup
+ end
+ alias to_str to_s
+
+ protected
+
+ attr_reader :version
+
+ def tokens
+ @tokens ||= tokenize
+ end
+
+ private
+
+ def max(a, b)
+ (a > b) ? a : b
+ end
+
+ def tokenize
+ version.scan(SCAN_PATTERN).map! do |token|
+ case token
+ when /\A#{AlphaToken::PATTERN}\z/o then AlphaToken
+ when /\A#{BetaToken::PATTERN}\z/o then BetaToken
+ when /\A#{RCToken::PATTERN}\z/o then RCToken
+ when /\A#{PreToken::PATTERN}\z/o then PreToken
+ when /\A#{PatchToken::PATTERN}\z/o then PatchToken
+ when /\A#{NumericToken::PATTERN}\z/o then NumericToken
+ when /\A#{StringToken::PATTERN}\z/o then StringToken
+ end.new(token)
+ end
end
end