diff options
194 files changed, 1520 insertions, 1309 deletions
diff --git a/.travis.yml b/.travis.yml index 94b83fc11..670e69ad0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: fast_finish: true include: - os: osx - osx_image: xcode8.3 + osx_image: xcode9 rvm: system - os: linux sudo: false @@ -21,19 +21,19 @@ before_install: - export HOMEBREW_NO_AUTO_UPDATE=1 - export HOMEBREW_DEVELOPER=1 - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then - git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; HOMEBREW_REPOSITORY="$(brew --repo)"; sudo chown -R "$USER" "$HOMEBREW_REPOSITORY/Library/Taps"; mv "$HOMEBREW_REPOSITORY/Library/Taps" "$PWD/Library"; sudo rm -rf "$HOMEBREW_REPOSITORY"; sudo ln -s "$PWD" "$HOMEBREW_REPOSITORY"; + git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; else umask 022; - git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; git fetch --unshallow; export PATH="$PWD/bin:$PATH"; HOMEBREW_CORE_TAP_DIR="$(brew --repo "homebrew/core")"; mkdir -p "$HOMEBREW_CORE_TAP_DIR"; + git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; HOMEBREW_TEST_BOT_TAP_DIR="$(brew --repo "homebrew/test-bot")"; ln -s "$HOMEBREW_TEST_BOT_TAP_DIR/.git" "$HOMEBREW_TEST_BOT_TAP_DIR/Formula" "$HOMEBREW_CORE_TAP_DIR"; fi diff --git a/CODEOFCONDUCT.md b/CODE_OF_CONDUCT.md index 9706e18f9..9706e18f9 100644 --- a/CODEOFCONDUCT.md +++ b/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5272c682..4729d6ca3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,5 @@ # Contributing to Homebrew -First time contributing to Homebrew? Read our [Code of Conduct](https://github.com/Homebrew/brew/blob/master/CODEOFCONDUCT.md#code-of-conduct). +First time contributing to Homebrew? Read our [Code of Conduct](https://github.com/Homebrew/brew/blob/master/CODE_OF_CONDUCT.md#code-of-conduct). ### Report a bug diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index dd6e039b0..7b3bdaeb6 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -63,26 +63,26 @@ Metrics/AbcSize: Max: 250 Metrics/BlockLength: - Max: 1250 + Max: 144 Metrics/ClassLength: - Max: 1500 + Max: 589 Metrics/CyclomaticComplexity: Max: 75 Metrics/LineLength: - Max: 400 + Max: 324 Metrics/MethodLength: - Max: 250 + Max: 222 Metrics/ModuleLength: CountComments: false - Exclude: - - '**/bin/**/*' - - '**/cmd/**/*' - - '**/lib/**/*' + Max: 367 + +Metrics/ParameterLists: + CountKeywordArgs: false Metrics/PerceivedComplexity: Max: 100 @@ -94,6 +94,9 @@ Performance/Caller: Style/Alias: EnforcedStyle: prefer_alias +Style/AsciiComments: + Enabled: false + Style/AutoResourceCleanup: Enabled: true diff --git a/Library/.auditcops.yml b/Library/.rubocop_audit.yml index b5b7a8b58..b5b7a8b58 100644 --- a/Library/.auditcops.yml +++ b/Library/.rubocop_audit.yml diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml index dc4406527..0e1fb2d04 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,20 +25,20 @@ Lint/NestedMethodDefinition: Lint/ParenthesesAsGroupedExpression: Enabled: true -Metrics/ParameterLists: - CountKeywordArgs: false +Metrics/BlockLength: + Max: 1250 -Style/BlockDelimiters: - Exclude: - - '**/*_spec.rb' +Metrics/BlockNesting: + Max: 5 -# so many of these in formulae but none in here -Style/GuardClause: - Enabled: true +Metrics/ClassLength: + Max: 1226 -# hash-rockets preferred for formulae, a: 1 preferred elsewhere -Style/HashSyntax: - EnforcedStyle: ruby19_no_mixed_keys +Metrics/LineLength: + Max: 244 + +Metrics/MethodLength: + Max: 195 # we won't change backward compatible method names Naming/MethodName: @@ -51,3 +50,16 @@ 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: + Enabled: true + +# hash-rockets preferred for formulae, a: 1 preferred elsewhere +Style/HashSyntax: + EnforcedStyle: ruby19_no_mixed_keys diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml deleted file mode 100644 index 96c2f3676..000000000 --- a/Library/Homebrew/.rubocop_todo.yml +++ /dev/null @@ -1,138 +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 -Naming/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' 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 2906fd93d..8c5386612 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! You're running #{RUBY_VERSION}." +end require "pathname" HOMEBREW_LIBRARY_PATH = Pathname.new(__FILE__).realpath.parent @@ -142,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/build.rb b/Library/Homebrew/build.rb index cd2fa4c02..836b360da 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -190,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 cb15ec051..1cbe49cf2 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact.rb @@ -25,44 +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. - # - CLASSES = [ - 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) - odebug "Determining which artifacts are present in Cask #{cask}" - CLASSES.flat_map { |klass| klass.for_cask(cask) } - 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 index 1b18cc6e7..f9f736662 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb @@ -1,6 +1,7 @@ module Hbc module Artifact class AbstractArtifact + include Comparable extend Predicable def self.english_name @@ -19,8 +20,45 @@ module Hbc @dirmethod ||= "#{dsl_key}dir".to_sym end - def self.for_cask(cask) - cask.artifacts[dsl_key].to_a + 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 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 4e8edbc11..a3075ff40 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb @@ -11,12 +11,6 @@ module Hbc dsl_key.to_s.prepend("uninstall_").to_sym end - def self.for_cask(cask) - [dsl_key, uninstall_dsl_key].flat_map do |key| - [*cask.artifacts[key]].map { |block| new(cask, key => block) } - end - end - attr_reader :directives def initialize(cask, **directives) diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb index badd549ce..3f63dae8f 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb @@ -37,7 +37,7 @@ module Hbc end def summarize - to_h.map { |key, val| [*val].map { |v| "#{key.inspect} => #{v.inspect}" }.join(", ") }.join(", ") + to_h.flat_map { |key, val| [*val].map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ") end private @@ -253,7 +253,7 @@ module Hbc end def trash_paths(*paths, command: nil, **_) - command.run!("/usr/bin/osascript", args: ["-e", <<-'EOS'.undent, *paths]) + 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) @@ -267,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 @@ -275,6 +275,9 @@ module Hbc end tell end run EOS + + # Remove AppleScript's automatic newline. + result.tap { |r| r.stdout.sub!(/\n$/, "") } end def uninstall_rmdir(*directories, command: nil, **_) diff --git a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb index 81adf9029..c9fd3dc27 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb @@ -16,6 +16,10 @@ module Hbc private + def summarize + path.relative_path_from(cask.staged_path).to_s + end + def extract(command: nil, verbose: nil, **_) container = Container.for_path(path, command) diff --git a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb index 0967fd99d..b4bdf3de6 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb @@ -9,17 +9,19 @@ module Hbc class Pkg < AbstractArtifact attr_reader :pkg_relative_path - def self.from_args(cask, path, **options) - options.extend(HashValidator).assert_valid_keys(:allow_untrusted, :choices) - new(cask, path, **options) + def self.from_args(cask, path, **stanza_options) + stanza_options.extend(HashValidator).assert_valid_keys( + :allow_untrusted, :choices + ) + new(cask, path, **stanza_options) end - attr_reader :path, :options + attr_reader :path, :stanza_options - def initialize(cask, path, **options) + def initialize(cask, path, **stanza_options) super(cask) @path = cask.staged_path.join(path) - @options = options + @stanza_options = stanza_options end def summarize @@ -32,7 +34,7 @@ module Hbc private - def run_installer(command: nil, verbose: false, **options) + 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." unless path.exist? @@ -43,7 +45,9 @@ module Hbc "-target", "/" ] args << "-verboseR" if verbose - args << "-allowUntrusted" if options.fetch(:allow_untrusted, false) + 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) @@ -51,7 +55,7 @@ module Hbc end def with_choices_file - choices = options.fetch(:choices, {}) + choices = stanza_options.fetch(:choices, {}) return yield nil if choices.empty? Tempfile.open(["choices", ".xml"]) do |file| diff --git a/Library/Homebrew/cask/lib/hbc/audit.rb b/Library/Homebrew/cask/lib/hbc/audit.rb index 03d8cce82..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 @@ -214,7 +218,7 @@ module Hbc end def check_generic_artifacts - cask.artifacts[:artifact].each do |artifact| + 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 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_loader.rb b/Library/Homebrew/cask/lib/hbc/cask_loader.rb index 8fce9636a..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::DEFAULT_PARSER.make_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 @@ -147,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 @@ -166,6 +171,7 @@ module Hbc def self.for(ref) [ FromInstanceLoader, + FromContentLoader, FromURILoader, FromTapLoader, FromTapPathLoader, diff --git a/Library/Homebrew/cask/lib/hbc/cli/edit.rb b/Library/Homebrew/cask/lib/hbc/cli/edit.rb index 8bce81c52..693edcd51 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/edit.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/edit.rb @@ -8,9 +8,6 @@ module Hbc end def run - 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} " @@ -18,6 +15,14 @@ module Hbc raise e.class.new(e.token, reason) end + def cask_path + casks.first.sourcefile_path + rescue CaskInvalidError + path = CaskLoader.path(args.first) + return path if path.file? + raise + end + def self.help "edits the given Cask" end diff --git a/Library/Homebrew/cask/lib/hbc/cli/info.rb b/Library/Homebrew/cask/lib/hbc/cli/info.rb index 9cdada62e..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,11 +77,11 @@ module Hbc def self.artifact_info(cask) ohai "Artifacts" - DSL::ORDINARY_ARTIFACT_CLASSES.flat_map { |klass| klass.for_cask(cask) } - .select { |artifact| artifact.respond_to?(:install_phase) } - .each do |artifact| - puts artifact.to_s - 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 end 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/list.rb b/Library/Homebrew/cask/lib/hbc/cli/list.rb index 32415af8a..4a50ae74a 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/list.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/list.rb @@ -23,14 +23,14 @@ 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).group_by(&:class).each do |klass, artifacts| + 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 diff --git a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb index 7e55db5f1..f2059605c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb @@ -16,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/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/dmg.rb b/Library/Homebrew/cask/lib/hbc/container/dmg.rb index 1d172a4b7..c0e43f68a 100644 --- a/Library/Homebrew/cask/lib/hbc/container/dmg.rb +++ b/Library/Homebrew/cask/lib/hbc/container/dmg.rb @@ -88,7 +88,7 @@ module Hbc bomfile.close Tempfile.open(["", ".list"]) do |filelist| - filelist.write(bom_filelist_from_path(mount)) + filelist.puts(bom_filelist_from_path(mount)) filelist.close @command.run!("/usr/bin/mkbom", args: ["-s", "-i", filelist.path, "--", bomfile.path]) @@ -98,16 +98,17 @@ module Hbc end def bom_filelist_from_path(mount) - Dir.chdir(mount) do - Dir.glob("**/*", File::FNM_DOTMATCH).map do |path| - next if skip_path?(Pathname(path)) - (path == ".") ? path : path.prepend("./") - end.compact.join("\n").concat("\n") - end + # We need to use `find` here instead of Ruby in order to properly handle + # file names containing special characters, such as “e” + “´” vs. “é”. + @command.run("/usr/bin/find", args: [".", "-print0"], chdir: mount, print_stderr: false).stdout + .split("\0") + .reject { |path| skip_path?(mount, path) } + .join("\n") end - def skip_path?(path) - dmg_metadata?(path) || system_dir_symlink?(path) + def skip_path?(mount, path) + path = Pathname(path.sub(%r{^\./}, "")) + dmg_metadata?(path) || system_dir_symlink?(mount, path) end # unnecessary DMG metadata @@ -130,9 +131,10 @@ module Hbc DMG_METADATA_FILES.include?(relative_root.basename.to_s) end - def system_dir_symlink?(path) + def system_dir_symlink?(mount, path) + full_path = Pathname(mount).join(path) # symlinks to system directories (commonly to /Applications) - path.symlink? && MacOS.system_dir?(path.readlink) + full_path.symlink? && MacOS.system_dir?(full_path.readlink) end def mounts_from_plist(plist) diff --git a/Library/Homebrew/cask/lib/hbc/dsl.rb b/Library/Homebrew/cask/lib/hbc/dsl.rb index 3824b9761..2db2c66a9 100644 --- a/Library/Homebrew/cask/lib/hbc/dsl.rb +++ b/Library/Homebrew/cask/lib/hbc/dsl.rb @@ -43,7 +43,7 @@ module Hbc Artifact::Zap, ].freeze - ACTIVATABLE_ARTIFACT_TYPES = (ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key) - [:stage_only]).freeze + ACTIVATABLE_ARTIFACT_CLASSES = ORDINARY_ARTIFACT_CLASSES - [Artifact::StageOnly] ARTIFACT_BLOCK_CLASSES = [ Artifact::PreflightBlock, @@ -63,6 +63,7 @@ module Hbc :gpg, :homepage, :language, + :languages, :name, :sha256, :staged_path, @@ -70,11 +71,12 @@ module Hbc :version, :appdir, *ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key), - *ACTIVATABLE_ARTIFACT_TYPES, + *ACTIVATABLE_ARTIFACT_CLASSES.map(&:dsl_key), *ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] }, ].freeze - attr_reader :token, :cask + attr_reader :cask, :token + def initialize(cask) @cask = cask @token = cask.token @@ -105,7 +107,9 @@ 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 @@ -117,7 +121,7 @@ module Hbc @language_blocks.default = block else - language_eval + raise CaskInvalidError.new(cask, "No block given to language stanza.") end end @@ -126,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) } @@ -139,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,7 +176,7 @@ module Hbc DSL::Container.new(*args).tap do |container| # TODO: remove this backward-compatibility section after removing nested_container if container&.nested - artifacts[:nested_container] << Artifact::NestedContainer.new(cask, container.nested) + artifacts.add(Artifact::NestedContainer.new(cask, container.nested)) end end end @@ -205,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,15 +251,13 @@ module Hbc end ORDINARY_ARTIFACT_CLASSES.each do |klass| - type = klass.dsl_key - - define_method(type) do |*args| + define_method(klass.dsl_key) do |*args| begin - if [*artifacts.keys, type].include?(:stage_only) && (artifacts.keys & ACTIVATABLE_ARTIFACT_TYPES).any? + 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 - artifacts[type].add(klass.from_args(cask, *args)) + artifacts.add(klass.from_args(cask, *args)) rescue CaskInvalidError raise rescue StandardError => e @@ -257,7 +269,7 @@ module Hbc ARTIFACT_BLOCK_CLASSES.each do |klass| [klass.dsl_key, klass.uninstall_dsl_key].each do |dsl_key| define_method(dsl_key) do |&block| - artifacts[dsl_key] << 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 fc7e83a20..f3994b81f 100644 --- a/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb +++ b/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb @@ -3,17 +3,17 @@ 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 curl_executable, *args = curl_args( - "--compressed", "--location", "--fail", @uri, + "--compressed", "--location", "--fail", uri, user_agent: :fake ) result = SystemCommand.run(curl_executable, args: args, print_stderr: false) @@ -30,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/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/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb index 01aae935d..68b9595e1 100644 --- a/Library/Homebrew/cask/lib/hbc/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/installer.rb @@ -126,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 @@ -177,7 +177,7 @@ module Hbc already_installed_artifacts = [] odebug "Installing artifacts" - artifacts = Artifact.for_cask(@cask) + artifacts = @cask.artifacts odebug "#{artifacts.length} artifact/s defined", artifacts artifacts.each do |artifact| @@ -374,7 +374,7 @@ module Hbc def uninstall_artifacts odebug "Un-installing artifacts" - artifacts = Artifact.for_cask(@cask) + artifacts = @cask.artifacts odebug "#{artifacts.length} artifact/s defined", artifacts @@ -388,7 +388,7 @@ module Hbc def zap ohai %Q(Implied "brew cask uninstall #{@cask}") uninstall_artifacts - if (zap_stanzas = Artifact::Zap.for_cask(@cask)).empty? + 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" diff --git a/Library/Homebrew/cask/lib/hbc/staged.rb b/Library/Homebrew/cask/lib/hbc/staged.rb index dc21279de..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 - @cask.artifacts[:app].to_a.at(index).target.join("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 be083c29e..9ce3de907 100644 --- a/Library/Homebrew/cask/lib/hbc/system_command.rb +++ b/Library/Homebrew/cask/lib/hbc/system_command.rb @@ -8,14 +8,14 @@ require "hbc/utils/hash_validator" module Hbc class SystemCommand - attr_reader :command + extend Predicable - def self.run(executable, options = {}) - new(executable, options).run! + def self.run(executable, **options) + new(executable, **options).run! end - def self.run!(command, options = {}) - run(command, options.merge(must_succeed: true)) + def self.run!(command, **options) + run(command, **options, must_succeed: true) end def run! @@ -26,38 +26,49 @@ module Hbc case type when :stdout processed_output[:stdout] << line - ohai line.chomp if options[:print_stdout] + ohai line.chomp if print_stdout? when :stderr processed_output[:stderr] << line - ohai line.chomp if options[:print_stderr] + ohai line.chomp if print_stderr? end end - assert_success if options[:must_succeed] + assert_success if must_succeed? result end - def initialize(executable, options) + def initialize(executable, args: [], sudo: false, input: [], print_stdout: false, print_stderr: true, must_succeed: false, **options) + executable, *args = Shellwords.shellescape(executable) if args.empty? + @executable = executable + @args = args + @sudo = sudo + @input = input + @print_stdout = print_stdout + @print_stderr = print_stderr + @must_succeed = must_succeed + options.extend(HashValidator).assert_valid_keys(:chdir) @options = options - process_options! + end + + def command + @command ||= [ + *sudo_prefix, + executable, + *args, + ].freeze end private - attr_reader :executable, :options, :processed_output, :processed_status - - def process_options! - options.extend(HashValidator) - .assert_valid_keys :input, :print_stdout, :print_stderr, :args, :must_succeed, :sudo - sudo_prefix = %w[/usr/bin/sudo -E --] - sudo_prefix = sudo_prefix.insert(1, "-A") unless ENV["SUDO_ASKPASS"].nil? - @command = [executable] - options[:print_stderr] = true unless options.key?(:print_stderr) - @command.unshift(*sudo_prefix) if options[:sudo] - @command.concat(options[:args]) if options.key?(:args) && !options[:args].empty? - @command[0] = Shellwords.shellescape(@command[0]) if @command.size == 1 - nil + attr_reader :executable, :args, :input, :options, :processed_output, :processed_status + + attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed? + + def sudo_prefix + return [] unless sudo? + askpass_flags = ENV.key?("SUDO_ASKPASS") ? ["-A"] : [] + ["/usr/bin/sudo", *askpass_flags, "-E", "--"] end def assert_success @@ -77,7 +88,7 @@ module Hbc def each_output_line(&b) raw_stdin, raw_stdout, raw_stderr, raw_wait_thr = - Open3.popen3(*expanded_command) + Open3.popen3(*expanded_command, **options) write_input_to(raw_stdin) raw_stdin.close_write @@ -87,7 +98,7 @@ module Hbc end def write_input_to(raw_stdin) - [*options[:input]].each { |line| raw_stdin.print line } + [*input].each(&raw_stdin.method(:print)) end def each_line_from(sources) 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 8c652657b..35020c5db 100644 --- a/Library/Homebrew/cask/lib/hbc/url.rb +++ b/Library/Homebrew/cask/lib/hbc/url.rb @@ -14,7 +14,7 @@ module Hbc end def initialize(uri, options = {}) - @uri = Hbc::UnderscoreSupportingURI.parse(uri) + @uri = URI(uri) @user_agent = options.fetch(:user_agent, :default) @cookies = options[:cookies] @referer = options[:referer] diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index 1849ea79b..ef8028339 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -161,49 +161,7 @@ class Caveats EOS end - def plist_caveats - s = [] - if f.plist || (keg&.plist_installed?) - plist_domain = f.plist_path.basename(".plist") - - # we readlink because this path probably doesn't exist since caveats - # occurs before the link step of installation - # Yosemite security measures mildly tighter rules: - # https://github.com/Homebrew/legacy-homebrew/issues/33815 - if !plist_path.file? || !plist_path.symlink? - if f.plist_startup - s << "To have launchd start #{f.full_name} now and restart at startup:" - s << " sudo brew services start #{f.full_name}" - else - s << "To have launchd start #{f.full_name} now and restart at login:" - s << " brew services start #{f.full_name}" - end - # For startup plists, we cannot tell whether it's running on launchd, - # as it requires for `sudo launchctl list` to get real result. - elsif f.plist_startup - s << "To restart #{f.full_name} after an upgrade:" - s << " sudo brew services restart #{f.full_name}" - elsif Kernel.system "/bin/launchctl list #{plist_domain} &>/dev/null" - s << "To restart #{f.full_name} after an upgrade:" - s << " brew services restart #{f.full_name}" - else - s << "To start #{f.full_name}:" - s << " brew services start #{f.full_name}" - end - - if f.plist_manual - s << "Or, if you don't want/need a background service you can just run:" - s << " #{f.plist_manual}" - end - - # pbpaste is the system clipboard tool on macOS and fails with `tmux` by default - # check if this is being run under `tmux` to avoid failing - if ENV["TMUX"] && !quiet_system("/usr/bin/pbpaste") - s << "" << "WARNING: brew services will fail when run under tmux." - end - end - s.join("\n") + "\n" unless s.empty? - end + def plist_caveats; end def plist_path destination = if f.plist_startup @@ -222,3 +180,5 @@ class Caveats destination_path/plist_filename end end + +require "extend/os/caveats" diff --git a/Library/Homebrew/cmd/commands.rb b/Library/Homebrew/cmd/commands.rb index addccd609..a3527bc94 100644 --- a/Library/Homebrew/cmd/commands.rb +++ b/Library/Homebrew/cmd/commands.rb @@ -16,12 +16,12 @@ module Homebrew else # Find commands in Homebrew/cmd puts "Built-in commands" - puts Formatter.columns(internal_commands) + puts Formatter.columns(internal_commands.sort) # Find commands in Homebrew/dev-cmd puts puts "Built-in developer commands" - puts Formatter.columns(internal_developer_commands) + puts Formatter.columns(internal_developer_commands.sort) # Find commands in the path unless (exts = external_commands).empty? diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index de7aa4a51..ae758e143 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -68,16 +68,16 @@ module Homebrew if mode.tree? if mode.installed? - puts_deps_tree Formula.installed, !ARGV.one? + puts_deps_tree Formula.installed.sort, !ARGV.one? else raise FormulaUnspecifiedError if ARGV.named.empty? puts_deps_tree ARGV.formulae, !ARGV.one? end elsif mode.all? - puts_deps Formula + puts_deps Formula.sort elsif ARGV.named.empty? raise FormulaUnspecifiedError unless mode.installed? - puts_deps Formula.installed + puts_deps Formula.installed.sort elsif mode.for_each? puts_deps ARGV.formulae else 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/info.rb b/Library/Homebrew/cmd/info.rb index 5eb033706..6ee24a7fa 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -67,9 +67,9 @@ module Homebrew def print_json ff = if ARGV.include? "--all" - Formula + Formula.sort elsif ARGV.include? "--installed" - Formula.installed + Formula.installed.sort else ARGV.formulae end 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/leaves.rb b/Library/Homebrew/cmd/leaves.rb index 4038aee4c..574ceb64e 100644 --- a/Library/Homebrew/cmd/leaves.rb +++ b/Library/Homebrew/cmd/leaves.rb @@ -9,7 +9,7 @@ module Homebrew module_function def leaves - installed = Formula.installed + installed = Formula.installed.sort deps_of_installed = Set.new installed.each do |f| diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb index 436fc1f97..263f33564 100644 --- a/Library/Homebrew/cmd/list.rb +++ b/Library/Homebrew/cmd/list.rb @@ -87,7 +87,7 @@ module Homebrew dirs.delete "etc" dirs.delete "var" - args = dirs + %w[-type f (] + args = dirs.sort + %w[-type f (] args.concat UNBREWED_EXCLUDE_FILES.flat_map { |f| %W[! -name #{f}] } args.concat UNBREWED_EXCLUDE_PATHS.flat_map { |d| %W[! -path #{d}] } args.concat %w[)] diff --git a/Library/Homebrew/cmd/missing.rb b/Library/Homebrew/cmd/missing.rb index 8a1dc506d..707ad6834 100644 --- a/Library/Homebrew/cmd/missing.rb +++ b/Library/Homebrew/cmd/missing.rb @@ -16,9 +16,9 @@ module Homebrew return unless HOMEBREW_CELLAR.exist? ff = if ARGV.named.empty? - Formula.installed + Formula.installed.sort else - ARGV.resolved_formulae + ARGV.resolved_formulae.sort end ff.each do |f| diff --git a/Library/Homebrew/cmd/options.rb b/Library/Homebrew/cmd/options.rb index 843d3a1ee..6bb6afafe 100644 --- a/Library/Homebrew/cmd/options.rb +++ b/Library/Homebrew/cmd/options.rb @@ -16,9 +16,9 @@ module Homebrew def options if ARGV.include? "--all" - puts_options Formula.to_a + puts_options Formula.to_a.sort elsif ARGV.include? "--installed" - puts_options Formula.installed + puts_options Formula.installed.sort else raise FormulaUnspecifiedError if ARGV.named.empty? puts_options ARGV.formulae 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 c01a11c10..d0f85a858 100644 --- a/Library/Homebrew/cmd/search.rb +++ b/Library/Homebrew/cmd/search.rb @@ -24,7 +24,7 @@ module Homebrew def search if ARGV.empty? - puts Formatter.columns(Formula.full_names) + puts Formatter.columns(Formula.full_names.sort) elsif ARGV.include? "--macports" exec_browser "https://www.macports.org/ports.php?by=name&substr=#{ARGV.next}" elsif ARGV.include? "--fink" @@ -52,15 +52,15 @@ module Homebrew results = search_taps(name) end - puts Formatter.columns(results) unless results.empty? + puts Formatter.columns(results.sort) 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? + puts Formatter.columns(local_results.sort) unless local_results.empty? tap_results = search_taps(query) - puts Formatter.columns(tap_results) unless tap_results.empty? + puts Formatter.columns(tap_results.sort) unless tap_results.empty? if $stdout.tty? count = local_results.length + tap_results.length diff --git a/Library/Homebrew/cmd/style.rb b/Library/Homebrew/cmd/style.rb index e816db5dc..89484d67d 100644 --- a/Library/Homebrew/cmd/style.rb +++ b/Library/Homebrew/cmd/style.rb @@ -109,7 +109,7 @@ module Homebrew args << "--config" << HOMEBREW_LIBRARY_PATH/".rubocop.yml" args << HOMEBREW_LIBRARY_PATH else - args << "--config" << HOMEBREW_LIBRARY/".auditcops.yml" + args << "--config" << HOMEBREW_LIBRARY/".rubocop_audit.yml" args += files end @@ -117,6 +117,7 @@ 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", "_#{HOMEBREW_RUBOCOP_VERSION}_", *args) diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb index cb0e0b387..d01ce8a02 100644 --- a/Library/Homebrew/cmd/tap-info.rb +++ b/Library/Homebrew/cmd/tap-info.rb @@ -21,10 +21,11 @@ module Homebrew module_function def tap_info + # TODO: This still returns a non-alphabetised list on APFS. if ARGV.include? "--installed" taps = Tap else - taps = ARGV.named.map do |name| + taps = ARGV.named.sort.map do |name| Tap.fetch(name) end end 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/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 781ee8808..e3d3c10bb 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -372,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) @@ -460,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 @@ -521,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 @@ -598,7 +598,7 @@ class ReporterHub return if formulae.empty? # Dump formula list. ohai title - puts Formatter.columns(formulae) + puts Formatter.columns(formulae.sort) end def installed?(formula) diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index e8211e4dd..3507fa92b 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -570,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..1688899f9 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,12 +119,13 @@ 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 return if uses.empty? - puts Formatter.columns(uses.map(&:full_name)) + puts Formatter.columns(uses.map(&:full_name).sort) odie "Missing formulae should not have dependents!" if used_formulae_missing end end diff --git a/Library/Homebrew/cmd/vendor-install.sh b/Library/Homebrew/cmd/vendor-install.sh index 6d16a297d..df8c2373c 100644 --- a/Library/Homebrew/cmd/vendor-install.sh +++ b/Library/Homebrew/cmd/vendor-install.sh @@ -81,9 +81,9 @@ fetch() { trap - SIGINT fi - if [[ -x "$(which shasum)" ]] + if [[ -x "/usr/bin/shasum" ]] then - sha="$(shasum -a 256 "$CACHED_LOCATION" | cut -d' ' -f1)" + sha="$(/usr/bin/shasum -a 256 "$CACHED_LOCATION" | cut -d' ' -f1)" elif [[ -x "$(which sha256sum)" ]] then sha="$(sha256sum "$CACHED_LOCATION" | cut -d' ' -f1)" diff --git a/Library/Homebrew/compat/formula.rb b/Library/Homebrew/compat/formula.rb index 853a38706..57ab84a76 100644 --- a/Library/Homebrew/compat/formula.rb +++ b/Library/Homebrew/compat/formula.rb @@ -78,4 +78,9 @@ class Formula def startup_plist odeprecated "Formula#startup_plist", "Formula#plist" end + + def rake(*args) + # odeprecated "FileUtils#rake", "system \"rake\"" + system "rake", *args + end end diff --git a/Library/Homebrew/compat/requirements.rb b/Library/Homebrew/compat/requirements.rb index 77760d1dc..3886cd7c7 100644 --- a/Library/Homebrew/compat/requirements.rb +++ b/Library/Homebrew/compat/requirements.rb @@ -17,3 +17,4 @@ PythonDependency = PythonRequirement TuntapDependency = TuntapRequirement X11Dependency = X11Requirement ConflictsWithBinaryOsxfuse = NonBinaryOsxfuseRequirement +MinimumMacOSRequirement = MacOSRequirement diff --git a/Library/Homebrew/debrew.rb b/Library/Homebrew/debrew.rb index 5bc3d2daa..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 @@ -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 069dbe676..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 diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index 0fbc2625b..7f0e7fbff 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -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..bc0246dd2 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) @@ -108,7 +105,8 @@ class DependencyCollector case spec when :x11 then X11Requirement.new(spec.to_s, tags) when :xcode then XcodeRequirement.new(tags) - when :macos then MinimumMacOSRequirement.new(tags) + when :linux then LinuxRequirement.new(tags) + when :macos then MacOSRequirement.new(tags) when :mysql then MysqlRequirement.new(tags) when :postgresql then PostgresqlRequirement.new(tags) when :gpg then GPG2Requirement.new(tags) 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 a7d498c0d..a9d27afa9 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -53,7 +53,7 @@ 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 @@ -387,8 +387,10 @@ class FormulaAuditor end end - # core aliases + tap alias names + tap alias full name - @@aliases ||= Formula.aliases + Formula.tap_aliases + def self.aliases + # core aliases + tap alias names + tap alias full name + @aliases ||= Formula.aliases + Formula.tap_aliases + end def audit_formula_name return unless @strict @@ -396,7 +398,6 @@ class FormulaAuditor 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." @@ -412,35 +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| - next if tap_formula_full_name.start_with?("homebrew/science/") - 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 - - same_name_tap_formulae = @@local_official_taps_name_map[name] || [] - - if @online - Homebrew.search_taps(name, silent: true).each do |tap_formula_full_name| - next if tap_formula_full_name.start_with?("homebrew/science/") - 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 + return if formula.core_formula? + return unless Formula.core_names.include?(name) - 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 @@ -468,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 @@ -479,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 @@ -616,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 @@ -993,6 +970,18 @@ class FormulaAuditor problem "Use `assert_match` instead of `assert ...include?`" end + if line =~ /(assert File\.exist\?|assert \(.*\)\.exist\?)/ + problem "Use `assert_predicate <path_to_file>, :exist?` instead of `#{Regexp.last_match(1)}`" + end + + if line =~ /(assert !File\.exist\?|assert !\(.*\)\.exist\?)/ + problem "Use `refute_predicate <path_to_file>, :exist?` instead of `#{Regexp.last_match(1)}`" + end + + if line =~ /(assert File\.executable\?|assert \(.*\)\.executable\?)/ + problem "Use `assert_predicate <path_to_file>, :executable?` instead of `#{Regexp.last_match(1)}`" + end + return unless @strict problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 8dfd0d12c..fb862c773 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -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 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/pull.rb b/Library/Homebrew/dev-cmd/pull.rb index cd0d6fbd0..aa3c9a9d7 100644 --- a/Library/Homebrew/dev-cmd/pull.rb +++ b/Library/Homebrew/dev-cmd/pull.rb @@ -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 @@ -560,7 +560,7 @@ module Homebrew req = Net::HTTP::Head.new bottle_info.url req.initialize_http_header "User-Agent" => HOMEBREW_USER_AGENT_RUBY res = http.request req - break if res.is_a?(Net::HTTPSuccess) + break if res.is_a?(Net::HTTPSuccess) || res.code == "302" unless res.is_a?(Net::HTTPClientError) raise "Failed to find published #{f} bottle at #{url} (#{res.code} #{res.message})!" diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index ab2b0edb0..6622a8c25 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -84,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/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 065f04240..9ab83c1a2 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" @@ -814,7 +816,7 @@ module Homebrew def check_for_linked_keg_only_brews return unless HOMEBREW_CELLAR.exist? - linked = Formula.installed.select do |f| + linked = Formula.installed.sort.select do |f| f.keg_only? && __check_linked_brew(f) end return if linked.empty? @@ -964,6 +966,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 @@ -978,6 +981,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 7012fccc8..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) } diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 5418f9331..22a7fe023 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -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/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index b518c22a1..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 @@ -324,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 ed5bfe6c3..34ef3869f 100644 --- a/Library/Homebrew/extend/fileutils.rb +++ b/Library/Homebrew/extend/fileutils.rb @@ -101,11 +101,6 @@ module FileUtils system Formulary.factory("scons").opt_bin/"scons", *args end - # Run the `rake` from the `ruby` Homebrew is using rather than whatever is in the `PATH`. - def rake(*args) - system RUBY_BIN/"rake", *args - end - # Run `make` 3.81 or newer. # Uses the system make on Leopard and newer, and the # path to the actually-installed make on Tiger or older. diff --git a/Library/Homebrew/extend/os/caveats.rb b/Library/Homebrew/extend/os/caveats.rb new file mode 100644 index 000000000..e67138087 --- /dev/null +++ b/Library/Homebrew/extend/os/caveats.rb @@ -0,0 +1 @@ +require "extend/os/mac/caveats" if OS.mac? diff --git a/Library/Homebrew/extend/os/mac/caveats.rb b/Library/Homebrew/extend/os/mac/caveats.rb new file mode 100644 index 000000000..d912a8307 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/caveats.rb @@ -0,0 +1,45 @@ +class Caveats + def plist_caveats + s = [] + if f.plist || (keg&.plist_installed?) + plist_domain = f.plist_path.basename(".plist") + + # we readlink because this path probably doesn't exist since caveats + # occurs before the link step of installation + # Yosemite security measures mildly tighter rules: + # https://github.com/Homebrew/legacy-homebrew/issues/33815 + if !plist_path.file? || !plist_path.symlink? + if f.plist_startup + s << "To have launchd start #{f.full_name} now and restart at startup:" + s << " sudo brew services start #{f.full_name}" + else + s << "To have launchd start #{f.full_name} now and restart at login:" + s << " brew services start #{f.full_name}" + end + # For startup plists, we cannot tell whether it's running on launchd, + # as it requires for `sudo launchctl list` to get real result. + elsif f.plist_startup + s << "To restart #{f.full_name} after an upgrade:" + s << " sudo brew services restart #{f.full_name}" + elsif Kernel.system "/bin/launchctl list #{plist_domain} &>/dev/null" + s << "To restart #{f.full_name} after an upgrade:" + s << " brew services restart #{f.full_name}" + else + s << "To start #{f.full_name}:" + s << " brew services start #{f.full_name}" + end + + if f.plist_manual + s << "Or, if you don't want/need a background service you can just run:" + s << " #{f.plist_manual}" + end + + # pbpaste is the system clipboard tool on macOS and fails with `tmux` by default + # check if this is being run under `tmux` to avoid failing + if ENV["TMUX"] && !quiet_system("/usr/bin/pbpaste") + s << "" << "WARNING: brew services will fail when run under tmux." + end + end + s.join("\n") + "\n" unless s.empty? + end +end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index e1acd1f77..e3d6880ba 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -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/formula.rb b/Library/Homebrew/formula.rb index d999b9c5f..61042aae7 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -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 @@ -1379,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) @@ -1642,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 @@ -1667,8 +1668,7 @@ class Formula end # @private - def test - end + def test; end # @private def test_fixtures(file) @@ -1683,8 +1683,7 @@ class Formula # system "./configure", "--prefix=#{prefix}" # system "make", "install" # end</pre> - def install - end + def install; end protected @@ -1932,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 b4f9db845..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,8 +85,7 @@ class FormulaInstaller return false if @pour_failed - bottle = formula.bottle - return false if !bottle && !formula.local_bottle_path + 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 @@ -101,6 +101,7 @@ class FormulaInstaller return false end + bottle = formula.bottle_specification unless bottle.compatible_cellar? if install_bottle_options[:warn] opoo <<-EOS.undent @@ -145,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? @@ -236,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? @@ -278,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? @@ -309,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) @@ -553,7 +568,7 @@ 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 @@ -709,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 @@ -770,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 @@ -801,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 @@ -809,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." @@ -821,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? @@ -831,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? @@ -891,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 dd67b4f24..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 diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb index 085748632..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 diff --git a/Library/Homebrew/locale.rb b/Library/Homebrew/locale.rb index d918e2a2a..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/ diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md index 715d8fd77..1c7c198b0 100644 --- a/Library/Homebrew/manpages/brew-cask.1.md +++ b/Library/Homebrew/manpages/brew-cask.1.md @@ -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. @@ -167,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`. 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/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/os/mac.rb b/Library/Homebrew/os/mac.rb index 15c301f99..9dbb252e4 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -47,19 +47,11 @@ module OS end def languages - return @languages unless @languages.nil? - - @languages = Utils.popen_read("defaults", "read", ".GlobalPreferences", "AppleLanguages").scan(/[^ \n"(),]+/) - - if ENV["HOMEBREW_LANGUAGES"] - @languages = ENV["HOMEBREW_LANGUAGES"].split(",") + @languages - end - - if ARGV.value("language") - @languages = ARGV.value("language").split(",") + @languages - end - - @languages = @languages.uniq + @languages ||= [ + *ARGV.value("language")&.split(","), + *ENV["HOMEBREW_LANGUAGES"]&.split(","), + *Open3.capture2("defaults", "read", "-g", "AppleLanguages")[0].scan(/[^ \n"(),]+/), + ].uniq end def language @@ -229,7 +221,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/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 59e7026bd..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 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/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.rb b/Library/Homebrew/requirements.rb index 553beb2a2..bac7d5790 100644 --- a/Library/Homebrew/requirements.rb +++ b/Library/Homebrew/requirements.rb @@ -2,7 +2,8 @@ require "requirement" require "requirements/fortran_requirement" require "requirements/gpg2_requirement" require "requirements/language_module_requirement" -require "requirements/minimum_macos_requirement" +require "requirements/linux_requirement" +require "requirements/macos_requirement" require "requirements/maximum_macos_requirement" require "requirements/mpi_requirement" require "requirements/osxfuse_requirement" diff --git a/Library/Homebrew/requirements/java_requirement.rb b/Library/Homebrew/requirements/java_requirement.rb index de3a33eb4..949978dbd 100644 --- a/Library/Homebrew/requirements/java_requirement.rb +++ b/Library/Homebrew/requirements/java_requirement.rb @@ -11,7 +11,7 @@ class JavaRequirement < Requirement end def initialize(tags) - @version = tags.shift if /(\d\.)+\d/ =~ tags.first + @version = tags.shift if /(\d+\.)+\d/ =~ tags.first super end @@ -103,7 +103,7 @@ class JavaRequirement < Requirement end def satisfies_version(java) - java_version_s = Utils.popen_read("#{java} -version 2>&1")[/1.\d/] + java_version_s = Utils.popen_read("#{java} -version 2>&1")[/\d+.\d/] return false unless java_version_s java_version = Version.create(java_version_s) needed_version = Version.create(version_without_plus) diff --git a/Library/Homebrew/requirements/linux_requirement.rb b/Library/Homebrew/requirements/linux_requirement.rb new file mode 100644 index 000000000..cb4666e56 --- /dev/null +++ b/Library/Homebrew/requirements/linux_requirement.rb @@ -0,0 +1,9 @@ +class LinuxRequirement < Requirement + fatal true + + satisfy(build_env: false) { OS.linux? } + + def message + "Linux is required." + end +end diff --git a/Library/Homebrew/requirements/macos_requirement.rb b/Library/Homebrew/requirements/macos_requirement.rb new file mode 100644 index 000000000..c89144d2c --- /dev/null +++ b/Library/Homebrew/requirements/macos_requirement.rb @@ -0,0 +1,31 @@ +require "requirement" + +class MacOSRequirement < Requirement + fatal true + + def initialize(tags = []) + @version = MacOS::Version.from_symbol(tags.first) unless tags.empty? + super + end + + def minimum_version_specified? + OS.mac? && @version + end + + satisfy(build_env: false) do + next MacOS.version >= @version if minimum_version_specified? + next true if OS.mac? + next true if @version + false + end + + def message + return "macOS is required." unless minimum_version_specified? + "macOS #{@version.pretty_name} or newer is required." + end + + def display_s + return "macOS is required" unless minimum_version_specified? + "macOS >= #{@version}" + end +end diff --git a/Library/Homebrew/requirements/minimum_macos_requirement.rb b/Library/Homebrew/requirements/minimum_macos_requirement.rb deleted file mode 100644 index 2cb63f740..000000000 --- a/Library/Homebrew/requirements/minimum_macos_requirement.rb +++ /dev/null @@ -1,20 +0,0 @@ -require "requirement" - -class MinimumMacOSRequirement < Requirement - fatal true - - def initialize(tags) - @version = MacOS::Version.from_symbol(tags.first) - super - end - - satisfy(build_env: false) { MacOS.version >= @version } - - def message - "macOS #{@version.pretty_name} or newer is required." - end - - def display_s - "macOS >= #{@version}" - end -end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 47dd2d803..fccce0ded 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -298,7 +298,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 diff --git a/Library/Homebrew/rubocops/formula_desc_cop.rb b/Library/Homebrew/rubocops/formula_desc_cop.rb index 2b613c9b4..2ef60303d 100644 --- a/Library/Homebrew/rubocops/formula_desc_cop.rb +++ b/Library/Homebrew/rubocops/formula_desc_cop.rb @@ -18,8 +18,14 @@ module RuboCop return end - # Check if a formula's desc is too long + # Check the formula's desc length. Should be >0 and <80 characters. desc = parameters(desc_call).first + pure_desc_length = string_content(desc).length + if pure_desc_length.zero? + problem "The desc (description) should not be an empty string." + return + end + desc_length = "#{@formula_name}: #{string_content(desc)}".length max_desc_length = 80 return if desc_length <= max_desc_length diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 01b13585c..a45f673c6 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -121,6 +121,7 @@ module RuboCop end find_instance_method_call(body_node, "ENV", :universal_binary) do + next if @formula_name == "wine" problem "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated." end 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/tab.rb b/Library/Homebrew/tab.rb index af19cabe6..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. @@ -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 fff58b754..c12c121e4 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) @@ -503,7 +500,7 @@ class Tap # an array of all installed {Tap} names. def self.names - map(&:name) + map(&:name).sort end # @private 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 02be796ed..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) { - -> { described_class.for_cask(cask).each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } } + 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 f67ffd31b..4ead8b7f9 100644 --- a/Library/Homebrew/test/cask/artifact/app_spec.rb +++ b/Library/Homebrew/test/cask/artifact/app_spec.rb @@ -1,8 +1,8 @@ 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) { described_class.for_cask(cask).first } + 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") } diff --git a/Library/Homebrew/test/cask/artifact/binary_spec.rb b/Library/Homebrew/test/cask/artifact/binary_spec.rb index 5ffaca861..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,8 +27,9 @@ describe Hbc::Artifact::Binary, :cask do end it "links the binary to the proper directory" do - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 @@ -35,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 } @@ -46,8 +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 - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 @@ -58,8 +61,9 @@ describe Hbc::Artifact::Binary, :cask do FileUtils.touch expected_path expect { - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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? @@ -68,8 +72,9 @@ describe Hbc::Artifact::Binary, :cask do it "clobbers an existing symlink" do expected_path.make_symlink("/tmp") - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + artifacts.each do |artifact| + artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) + end expect(File.readlink(expected_path)).not_to eq("/tmp") end @@ -77,24 +82,27 @@ describe Hbc::Artifact::Binary, :cask do it "creates parent directory if it doesn't exist" do FileUtils.rmdir Hbc.binarydir - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 bec8c2742..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) { - -> { described_class.for_cask(cask).each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } } + 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") } @@ -15,7 +19,7 @@ describe Hbc::Artifact::Artifact, :cask do context "without target" do it "fails to load" do expect { - Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-generic-artifact-no-target.rb") + 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 41d143764..f9cd056f8 100644 --- a/Library/Homebrew/test/cask/artifact/nested_container_spec.rb +++ b/Library/Homebrew/test/cask/artifact/nested_container_spec.rb @@ -1,12 +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 - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 c6a45c49a..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 = described_class.for_cask(cask).first + pkg = cask.artifacts.find { |a| a.is_a?(described_class) } expect(fake_system_command).to receive(:run!).with( "/usr/sbin/installer", @@ -22,10 +22,10 @@ describe Hbc::Artifact::Pkg, :cask do 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 = described_class.for_cask(cask).first + pkg = cask.artifacts.find { |a| a.is_a?(described_class) } file = double(path: Pathname.new("/tmp/choices.xml")) diff --git a/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb b/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb index 4a44bb59b..18cc4ca91 100644 --- a/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb +++ b/Library/Homebrew/test/cask/artifact/postflight_block_spec.rb @@ -11,8 +11,9 @@ describe Hbc::Artifact::PostflightBlock, :cask do end end - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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) @@ -31,8 +32,9 @@ describe Hbc::Artifact::PostflightBlock, :cask do end end - described_class.for_cask(cask) - .each { |artifact| artifact.uninstall_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 d7d4e72d9..405cdbd6f 100644 --- a/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb +++ b/Library/Homebrew/test/cask/artifact/preflight_block_spec.rb @@ -11,8 +11,9 @@ describe Hbc::Artifact::PreflightBlock, :cask do end end - described_class.for_cask(cask) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 @@ -31,8 +32,9 @@ describe Hbc::Artifact::PreflightBlock, :cask do end end - described_class.for_cask(cask) - .each { |artifact| artifact.uninstall_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 2f913fecc..80d3e917f 100644 --- a/Library/Homebrew/test/cask/artifact/suite_spec.rb +++ b/Library/Homebrew/test/cask/artifact/suite_spec.rb @@ -1,8 +1,12 @@ describe Hbc::Artifact::Suite, :cask do - let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-suite.rb") } + let(:cask) { Hbc::CaskLoader.load(cask_path("with-suite")) } let(:install_phase) { - -> { described_class.for_cask(cask).each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } } + 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") } 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 f6e0d3c97..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) { - -> { described_class.for_cask(cask).each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } } + 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 d6a8393da..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) { - described_class.for_cask(cask).first + 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 06eec4a01..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_dsl_key) { described_class.dsl_key } - let(:artifact) { described_class.for_cask(cask).first } + let(:artifact) { cask.artifacts.find { |a| a.is_a?(described_class) } } let(:fake_system_command) { Hbc::FakeSystemCommand } 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_dsl_key}-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_dsl_key}-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_dsl_key}-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_dsl_key}-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_dsl_key}-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,7 +172,7 @@ 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_dsl_key}-#{directive}.rb") } + let(:cask) { Hbc::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-#{directive}")) } before(:each) do allow_any_instance_of(Hbc::Artifact::AbstractUninstall).to receive(:trash_paths) @@ -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_dsl_key}-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") } @@ -224,7 +226,7 @@ shared_examples "#uninstall_phase or #zap_phase" do context "using #{script_type.inspect}" do let(:fake_system_command) { Hbc::NeverSudoSystemCommand } let(:token) { "with-#{artifact_dsl_key}-#{script_type}".tr("_", "-") } - 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(: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_dsl_key}-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/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/cli/audit_spec.rb b/Library/Homebrew/test/cask/cli/audit_spec.rb index 30ab437cb..da8bf1273 100644 --- a/Library/Homebrew/test/cask/cli/audit_spec.rb +++ b/Library/Homebrew/test/cask/cli/audit_spec.rb @@ -1,6 +1,10 @@ +require_relative "shared_examples/invalid_option" + describe Hbc::CLI::Audit, :cask do 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 @@ -9,7 +13,7 @@ describe Hbc::CLI::Audit, :cask do 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 @@ -20,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 @@ -31,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 @@ -40,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 @@ -51,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 @@ -60,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 5a4b29c6f..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,41 +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") } + expect { described_class.run("notacask") } .to raise_error(Hbc::CaskUnavailableError, /is unavailable/) 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 - 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 17d426f78..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")) @@ -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 51542807f..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")) @@ -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 faaa69b35..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") + described_class.run("notacask") }.to raise_error(Hbc::CaskUnavailableError) 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 - 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 aec7080de..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 @@ -38,20 +44,14 @@ describe Hbc::CLI::Info, :cask do 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 @@ -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 @@ -90,19 +90,35 @@ describe Hbc::CLI::Info, :cask do 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 e30489789..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,95 +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") + described_class.run("notacask") }.to raise_error(Hbc::CaskUnavailableError) end it "returns a suggestion for a misspelled Cask" do expect { - Hbc::CLI::Install.run("localcaffeine") + 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 { - Hbc::CLI::Install.run("local") + 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 - - 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 - end end diff --git a/Library/Homebrew/test/cask/cli/list_spec.rb b/Library/Homebrew/test/cask/cli/list_spec.rb index d2d7efd3b..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,7 +11,7 @@ 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 @@ -26,7 +30,7 @@ describe Hbc::CLI::List, :cask do end expect { - Hbc::CLI::List.run("--full-name") + described_class.run("--full-name") }.to output(<<-EOS.undent).to_stdout local-caffeine local-transmission @@ -49,30 +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.for_cask(transmission) - .each { |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) } + 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 3d58e6a15..a4f796f3c 100644 --- a/Library/Homebrew/test/cask/cli/search_spec.rb +++ b/Library/Homebrew/test/cask/cli/search_spec.rb @@ -1,8 +1,12 @@ +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([]) 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 2ec506839..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,29 +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") } + 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") } + 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 @@ -40,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 @@ -49,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 @@ -57,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 @@ -65,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 @@ -73,13 +79,13 @@ describe Hbc::CLI::Uninstall, :cask do Hbc.appdir.join("MyFancyApp.app").rmtree - expect { Hbc::CLI::Uninstall.run("with-uninstall-script-app") } + 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 @@ -112,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 @@ -127,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 @@ -157,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 502bf8e69..05c882854 100644 --- a/Library/Homebrew/test/cask/cli/zap_spec.rb +++ b/Library/Homebrew/test/cask/cli/zap_spec.rb @@ -1,12 +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") } + 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 @@ -14,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 @@ -45,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 index 00dc252fe..81c22ded6 100644 --- a/Library/Homebrew/test/cask/conflicts_with_spec.rb +++ b/Library/Homebrew/test/cask/conflicts_with_spec.rb @@ -1,11 +1,11 @@ describe "conflicts_with", :cask do describe "conflicts_with cask" do let(:local_caffeine) { - Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") + Hbc::CaskLoader.load(cask_path("local-caffeine")) } let(:with_conflicts_with) { - Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-conflicts-with.rb") + Hbc::CaskLoader.load(cask_path("with-conflicts-with")) } it "installs the dependency of a Cask and the Cask itself" do 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 fb92a9a24..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 comparison" do - let(:cask) { Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-depends-on-macos-comparison.rb") } + 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/dsl/appcast_spec.rb b/Library/Homebrew/test/cask/dsl/appcast_spec.rb index ccc6a4633..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 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 aec1e917f..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(cask.artifacts[:app].map(&:to_s)).to eq(["Foo.app (App)", "Bar.app (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(cask.artifacts[:app]).to be_empty + expect(cask.artifacts).to be_empty end end @@ -219,7 +249,7 @@ describe Hbc::DSL, :cask do pkg "Bar.pkg" end - expect(cask.artifacts[:pkg].map(&:to_s)).to eq(["Foo.pkg (Pkg)", "Bar.pkg (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.path).to eq(Pathname("/usr/bin/true")) - expect(cask.artifacts[:installer].first.args[:args]).to eq(["--flag"]) - expect(cask.artifacts[:installer].to_a[1].path).to eq(Pathname("/usr/bin/false")) - expect(cask.artifacts[:installer].to_a[1].args[: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,7 @@ describe Hbc::DSL, :cask do let(:token) { "with-installer-manual" } it "allows installer manual to be specified" do - installer = cask.artifacts[:installer].first + 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 @@ -494,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]).not_to be_empty + expect(cask.artifacts).to contain_exactly a_kind_of Hbc::Artifact::StageOnly end end @@ -515,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.source).to eq(Hbc.appdir/"some/path") + expect(cask.artifacts.first.source).to eq(Hbc.appdir/"some/path") end end @@ -533,10 +563,35 @@ describe Hbc::DSL, :cask do binary "#{appdir}/some/path" end - expect(cask.artifacts[:binary].first.source).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/cmd/style_spec.rb b/Library/Homebrew/test/cmd/style_spec.rb index 4701036f1..9bc8fcab1 100644 --- a/Library/Homebrew/test/cmd/style_spec.rb +++ b/Library/Homebrew/test/cmd/style_spec.rb @@ -4,12 +4,12 @@ describe "brew style" do around(:each) do |example| begin FileUtils.ln_s HOMEBREW_LIBRARY_PATH, HOMEBREW_LIBRARY/"Homebrew" - FileUtils.ln_s HOMEBREW_LIBRARY_PATH.parent/".rubocop.yml", HOMEBREW_LIBRARY/".auditcops.yml" + FileUtils.ln_s HOMEBREW_LIBRARY_PATH.parent/".rubocop.yml", HOMEBREW_LIBRARY/".rubocop_audit.yml" example.run ensure FileUtils.rm_f HOMEBREW_LIBRARY/"Homebrew" - FileUtils.rm_f HOMEBREW_LIBRARY/".auditcops.yml" + FileUtils.rm_f HOMEBREW_LIBRARY/".rubocop_audit.yml" end end 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/os_requirement_spec.rb b/Library/Homebrew/test/os_requirement_spec.rb new file mode 100644 index 000000000..87f86231c --- /dev/null +++ b/Library/Homebrew/test/os_requirement_spec.rb @@ -0,0 +1,18 @@ +require "requirements/linux_requirement" +require "requirements/macos_requirement" + +describe LinuxRequirement do + describe "#satisfied?" do + it "returns true if OS is Linux" do + expect(subject.satisfied?).to eq(OS.linux?) + end + end +end + +describe MacOSRequirement do + describe "#satisfied?" do + it "returns true if OS is macOS" do + expect(subject.satisfied?).to eq(OS.mac?) + end + 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 index 676dd4f6e..59252587c 100644 --- a/Library/Homebrew/test/rubocops/class_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/class_cop_spec.rb @@ -29,7 +29,7 @@ describe RuboCop::Cop::FormulaAudit::ClassName do column: 12, source: source }] - inspect_source(cop, source) + inspect_source(source) expected_offenses.zip(cop.offenses.reverse).each do |expected, actual| expect_offense(expected, actual) @@ -49,7 +49,7 @@ describe RuboCop::Cop::FormulaAudit::ClassName do end EOS - new_source = autocorrect_source(cop, source) + new_source = autocorrect_source(source) expect(new_source).to eq(corrected_source) end end @@ -71,7 +71,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Test 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) 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 3af0f9669..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, "/homebrew-core/Formula/foo@2.0.rb") + 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, "/homebrew-core/Formula/foo@2.0.rb") + 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 48342e8bc..4816c3b26 100644 --- a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb @@ -20,13 +20,34 @@ 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) end end + it "reports an offense when desc is an empty string" do + source = <<-EOS.undent + class Foo < Formula + url 'http://example.com/foo-1.0.tgz' + desc '' + end + EOS + + msg = "The desc (description) should not be an empty string." + expected_offenses = [{ message: msg, + severity: :convention, + line: 3, + column: 2, + source: source }] + + inspect_source(source, "/homebrew-core/Formula/foo.rb") + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + it "When desc is too long" do source = <<-EOS.undent class Foo < Formula @@ -45,7 +66,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do column: 2, source: source }] - inspect_source(cop, source, "/homebrew-core/Formula/foo.rb") + inspect_source(source, "/homebrew-core/Formula/foo.rb") expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end @@ -70,7 +91,7 @@ describe RuboCop::Cop::FormulaAuditStrict::DescLength do column: 2, source: source }] - inspect_source(cop, source, "/homebrew-core/Formula/foo.rb") + inspect_source(source, "/homebrew-core/Formula/foo.rb") expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end @@ -96,7 +117,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 +137,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 +157,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 +177,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do column: 8, source: source }] - inspect_source(cop, source, "/homebrew-core/Formula/foo.rb") + inspect_source(source, "/homebrew-core/Formula/foo.rb") expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end @@ -176,7 +197,7 @@ describe RuboCop::Cop::FormulaAuditStrict::Desc do end EOS - corrected_source = autocorrect_source(cop, source, "/homebrew-core/Formula/foo.rb") + 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 d93962688..af816a5a9 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) @@ -70,7 +70,7 @@ describe RuboCop::Cop::FormulaAudit::ClassInheritance 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) @@ -82,7 +82,7 @@ end describe RuboCop::Cop::FormulaAudit::Comments do subject(:cop) { described_class.new } - context "When auditing formula" do + context "When auditing formulae" do it "with commented cmake call" do source = <<-EOS.undent class Foo < Formula @@ -98,7 +98,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) @@ -120,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) @@ -142,7 +142,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) @@ -154,7 +154,7 @@ end describe RuboCop::Cop::FormulaAudit::Miscellaneous do subject(:cop) { described_class.new } - context "When auditing formula" do + context "When auditing formulae" do it "with FileUtils" do source = <<-EOS.undent class Foo < Formula @@ -170,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) @@ -194,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) @@ -219,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) @@ -246,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) @@ -274,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) @@ -299,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) @@ -324,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) @@ -349,7 +349,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) @@ -373,14 +373,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 build.universal? exempted formula" do + it "with a build.universal? exemption reports no offenses" do source = <<-EOS.undent class Wine < Formula desc "foo" @@ -391,8 +391,8 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - inspect_source(cop, source, "/homebrew-core/Formula/wine.rb") - expect(cop.offenses).to eq([]) + inspect_source(source, "/homebrew-core/Formula/wine.rb") + expect(cop.offenses).to be_empty end it "with ENV.universal_binary" do @@ -412,14 +412,29 @@ 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 an ENV.universal_binary exemption reports no offenses" do + source = <<-EOS.undent + class Wine < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + if build? + ENV.universal_binary + end + end + EOS + + inspect_source(source, "/homebrew-core/Formula/wine.rb") + expect(cop.offenses).to be_empty + end + + it "with ENV.x11" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -436,7 +451,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) @@ -458,7 +473,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) @@ -474,7 +489,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - inspect_source(cop, source, "/homebrew-core/Formula/cctools.rb") + inspect_source(source, "/homebrew-core/Formula/cctools.rb") expect(cop.offenses).to eq([]) end @@ -493,7 +508,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) @@ -509,7 +524,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - inspect_source(cop, source, "/homebrew-core/Formula/kibana@4.4.rb") + inspect_source(source, "/homebrew-core/Formula/kibana@4.4.rb") expect(cop.offenses).to eq([]) 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 28915a1ec..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 @@ -34,7 +34,7 @@ describe RuboCop::Cop::FormulaAudit::Patches 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) @@ -61,7 +61,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do end EOS - inspect_source(cop, source) + inspect_source(source) expected_offense = if patch_url =~ %r{/raw\.github\.com/} [{ message: <<-EOS.undent.chomp, GitHub/Gist patches should specify a revision: @@ -154,7 +154,7 @@ describe RuboCop::Cop::FormulaAudit::Patches 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) @@ -183,7 +183,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do end EOS - inspect_source(cop, source) + inspect_source(source) expected_offense = if patch_url =~ %r{/raw\.github\.com/} [{ message: <<-EOS.undent.chomp, GitHub/Gist patches should specify a revision: diff --git a/Library/Homebrew/test/rubocops/text_cop_spec.rb b/Library/Homebrew/test/rubocops/text_cop_spec.rb index ec13c4041..490801770 100644 --- a/Library/Homebrew/test/rubocops/text_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/text_cop_spec.rb @@ -24,7 +24,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) @@ -48,7 +48,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) @@ -73,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) @@ -98,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) @@ -123,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) @@ -148,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) @@ -173,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) @@ -210,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) @@ -237,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) @@ -267,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) @@ -292,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 e51fb6be0..ad939a1a2 100644 --- a/Library/Homebrew/test/rubocops/urls_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/urls_cop_spec.rb @@ -126,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) @@ -160,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) @@ -183,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) @@ -222,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 Binary files differindex 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 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/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/version_spec.rb b/Library/Homebrew/test/version_spec.rb index d670d79c8..d0393afa6 100644 --- a/Library/Homebrew/test/version_spec.rb +++ b/Library/Homebrew/test/version_spec.rb @@ -649,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 3033eb4dd..237ffa74e 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -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 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/fork.rb b/Library/Homebrew/utils/fork.rb index 2f2a403e2..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,7 +39,7 @@ 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 "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success? end 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 @@ -22,7 +22,7 @@ Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshootin [](https://travis-ci.org/Homebrew/brew) [](https://codecov.io/gh/Homebrew/brew) -We'd love you to contribute to Homebrew. First, please read our [Contribution Guide](https://github.com/Homebrew/brew/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Homebrew/brew/blob/master/CODEOFCONDUCT.md#code-of-conduct). +We'd love you to contribute to Homebrew. First, please read our [Contribution Guide](https://github.com/Homebrew/brew/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Homebrew/brew/blob/master/CODE_OF_CONDUCT.md#code-of-conduct). We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour. diff --git a/docs/External-Commands.md b/docs/External-Commands.md index e1178ceda..881a1293a 100644 --- a/docs/External-Commands.md +++ b/docs/External-Commands.md @@ -44,12 +44,12 @@ Note they are largely untested, and as always, be careful about running untested ### brew-livecheck Check if there is a new upstream version of a formula. -See the [`README`](https://github.com/youtux/homebrew-livecheck/blob/master/README.md) for more info and usage. +See the [`README`](https://github.com/Homebrew/homebrew-livecheck/blob/master/README.md) for more info and usage. Install using: ```sh -brew tap youtux/livecheck +brew tap homebrew/livecheck ``` ### brew-gem diff --git a/docs/Interesting-Taps-and-Forks.md b/docs/Interesting-Taps-and-Forks.md index 6b70fadec..5e3fc19d2 100644 --- a/docs/Interesting-Taps-and-Forks.md +++ b/docs/Interesting-Taps-and-Forks.md @@ -5,11 +5,9 @@ Homebrew has the capability to add (and remove) multiple taps to your local inst ## Main taps -* [homebrew/apache](https://github.com/Homebrew/homebrew-apache): A tap for Apache modules, extending macOS's built-in Apache. These brews may require unconventional additional setup, as explained in the caveats. +* [homebrew/nginx](https://github.com/Homebrew/homebrew-nginx): A tap for NGINX modules, intended for its `nginx-full` formula which includes more module options. -* [homebrew/nginx](https://github.com/Homebrew/homebrew-nginx): Feature rich Nginx tap for modules. - -* [homebrew/php](https://github.com/Homebrew/homebrew-php): Repository for php-related formulae. +* [homebrew/php](https://github.com/Homebrew/homebrew-php): Repository for PHP-related formulae. * [homebrew/science](https://github.com/Homebrew/homebrew-science): A collection of scientific libraries and tools. @@ -21,8 +19,6 @@ You can be added as a maintainer for one of the Homebrew organization taps and a * [InstantClientTap/instantclient](https://github.com/InstantClientTap/homebrew-instantclient): A tap for Oracle Instant Client. The packages need to be downloaded manually. -* [besport/ocaml](https://github.com/besport/homebrew-ocaml): A tap for Ocaml libraries, though with caveats, it requires you install its customized ocaml formula. Perhaps a template for more work. - * [osx-cross/avr](https://github.com/osx-cross/homebrew-avr): GNU AVR toolchain (Libc, compilers and other tools for Atmel MCUs, useful for Arduino hackers and AVR programmers). * [petere/postgresql](https://github.com/petere/homebrew-postgresql): Allows installing multiple PostgreSQL versions in parallel. @@ -31,6 +27,10 @@ You can be added as a maintainer for one of the Homebrew organization taps and a * [dunn/emacs](https://github.com/dunn/homebrew-emacs): A tap for Emacs packages. +* [sidaf/pentest](https://github.com/sidaf/homebrew-pentest): Tools for penetration testing. + +* [osrf/simulation](https://github.com/osrf/homebrew-simulation): Tools for robotics simulation. + ## Interesting forks * [mistydemeo/tigerbrew](https://github.com/mistydemeo/tigerbrew): Experimental Tiger PowerPC version diff --git a/docs/Kickstarter-Supporters.md b/docs/Kickstarter-Supporters.md index 84ba662b4..146718aec 100644 --- a/docs/Kickstarter-Supporters.md +++ b/docs/Kickstarter-Supporters.md @@ -379,7 +379,7 @@ These wonderful people supported our Kickstarter by giving us £10 or more: * [Andrew Brown](http://pvalu.es) * [Bethany Sumner](http://www.bethanysumner.com/) * [Orta](http://orta.io) -* [Michał Gołębiowski](https://github.com/mgol) +* [Michał Gołębiowski-Owczarek](https://github.com/mgol) * [Adam C. Foltzer](http://www.acfoltzer.net/) * [Steve Hiemstra](https://www.speg.com) * [Anton Sipos](http://www.softwarefuturism.com) diff --git a/manpages/brew-cask.1 b/manpages/brew-cask.1 index f8f58a123..f2acf1842 100644 --- a/manpages/brew-cask.1 +++ b/manpages/brew-cask.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW\-CASK" "1" "August 2017" "Homebrew" "brew-cask" +.TH "BREW\-CASK" "1" "September 2017" "Homebrew" "brew-cask" . .SH "NAME" \fBbrew\-cask\fR \- a friendly binary installer for macOS @@ -18,7 +18,7 @@ Homebrew\-Cask works robustly enough that we welcome new users, but the project .SH "FREQUENTLY USED COMMANDS" . .TP -\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] \fItoken\fR [ \fItoken\fR \.\.\. ] +\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] [\-\-language=\fIiso\-language\fR[,\fIiso\-language\fR \.\.\. ]] \fItoken\fR [ \fItoken\fR \.\.\. ] Install Cask identified by \fItoken\fR\. . .TP @@ -35,7 +35,7 @@ The tokens returned by \fBsearch\fR are suitable as arguments for most other com .SH "COMMANDS" . .TP -\fBaudit\fR [ \fItoken\fR \.\.\. ] +\fBaudit\fR [\-\-language=\fIiso\-language\fR[,\fIiso\-language\fR \.\.\. ]] [ \fItoken\fR \.\.\. ] Check the given Casks for installability\. If no tokens are given on the command line, all Casks are audited\. . .TP @@ -169,6 +169,10 @@ Give additional feedback during installation\. Target location for Applications\. The default value is \fB/Applications\fR\. . .TP +\fB\-\-language=<iso\-language>[,<iso\-language> \.\.\. ]]\fR +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 \fBlanguage of your system\fR\. +. +.TP \fB\-\-colorpickerdir=<path>\fR Target location for Color Pickers\. The default value is \fB~/Library/ColorPickers\fR\. . diff --git a/manpages/brew.1 b/manpages/brew.1 index 362e884ed..b3d840275 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW" "1" "August 2017" "Homebrew" "brew" +.TH "BREW" "1" "September 2017" "Homebrew" "brew" . .SH "NAME" \fBbrew\fR \- The missing package manager for macOS |
