diff options
Diffstat (limited to 'Library')
41 files changed, 473 insertions, 351 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb index 01e98ac35..eaaa49e20 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb @@ -31,20 +31,26 @@ module Hbc ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'." target.dirname.mkpath - FileUtils.move(source, target) + + if target.parent.writable? + FileUtils.move(source, target) + else + SystemCommand.run("/bin/mv", args: [source, target], sudo: true) + end + add_altname_metadata target, source.basename.to_s end def delete ohai "Removing #{self.class.artifact_english_name} '#{target}'." - return unless Utils.path_occupied?(target) - raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}." if MacOS.undeletable?(target) - if force - Utils.gain_permissions_remove(target, command: @command) - else + return unless Utils.path_occupied?(target) + + if target.parent.writable? && !force target.rmtree + else + Utils.gain_permissions_remove(target, command: @command) end end diff --git a/Library/Homebrew/cask/lib/hbc/container.rb b/Library/Homebrew/cask/lib/hbc/container.rb index fc7246f3d..c6b2c3c37 100644 --- a/Library/Homebrew/cask/lib/hbc/container.rb +++ b/Library/Homebrew/cask/lib/hbc/container.rb @@ -4,6 +4,7 @@ require "hbc/container/bzip2" require "hbc/container/cab" require "hbc/container/criteria" require "hbc/container/dmg" +require "hbc/container/executable" require "hbc/container/generic_unar" require "hbc/container/gzip" require "hbc/container/lzma" @@ -39,6 +40,7 @@ module Hbc Gzip, # pure gzip Lzma, # pure lzma Xz, # pure xz + Executable, ] # for explicit use only (never autodetected): # Hbc::Container::Naked diff --git a/Library/Homebrew/cask/lib/hbc/container/executable.rb b/Library/Homebrew/cask/lib/hbc/container/executable.rb new file mode 100644 index 000000000..848f6d4be --- /dev/null +++ b/Library/Homebrew/cask/lib/hbc/container/executable.rb @@ -0,0 +1,18 @@ +require "hbc/container/naked" +require "vendor/macho/macho" + +module Hbc + class Container + class Executable < Naked + def self.me?(criteria) + return true if criteria.magic_number(/^#!\s*\S+/) + + begin + MachO.open(criteria.path).header.executable? + rescue MachO::MagicError + false + end + end + end + end +end diff --git a/Library/Homebrew/cask/lib/hbc/utils.rb b/Library/Homebrew/cask/lib/hbc/utils.rb index 3fc817dd5..ecb565e8e 100644 --- a/Library/Homebrew/cask/lib/hbc/utils.rb +++ b/Library/Homebrew/cask/lib/hbc/utils.rb @@ -4,8 +4,7 @@ require "stringio" require "hbc/utils/file" -PREBUG_URL = "https://github.com/caskroom/homebrew-cask/blob/master/doc/reporting_bugs/pre_bug_report.md".freeze -ISSUES_URL = "https://github.com/caskroom/homebrew-cask#reporting-bugs".freeze +BUG_REPORTS_URL = "https://github.com/caskroom/homebrew-cask#reporting-bugs".freeze # monkeypatch Object - not a great idea class Object @@ -39,7 +38,15 @@ module Hbc module Utils def self.gain_permissions_remove(path, command: SystemCommand) if path.respond_to?(:rmtree) && path.exist? - gain_permissions(path, ["-R"], command, &:rmtree) + gain_permissions(path, ["-R"], command) do |p| + if p.parent.writable? + p.rmtree + else + command.run("/bin/rm", + args: command_args + ["-r", "-f", "--", p], + sudo: true) + end + end elsif File.symlink?(path) gain_permissions(path, ["-h"], command, &FileUtils.method(:rm_f)) end @@ -96,11 +103,7 @@ module Hbc def self.error_message_with_suggestions <<-EOS.undent Follow the instructions here: - #{Formatter.url(PREBUG_URL)} - - If this doesn’t fix the problem, please report this bug: - #{Formatter.url(ISSUES_URL)} - + #{Formatter.url(BUG_REPORTS_URL)} EOS end diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 615a7ce9e..d1f0b2516 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -6,7 +6,9 @@ module Homebrew module Cleanup @disk_cleanup_size = 0 - def self.cleanup + module_function + + def cleanup cleanup_cellar cleanup_cache cleanup_logs @@ -15,34 +17,41 @@ module Homebrew rm_ds_store end - def self.update_disk_cleanup_size(path_size) + def update_disk_cleanup_size(path_size) @disk_cleanup_size += path_size end - def self.disk_cleanup_size + def disk_cleanup_size @disk_cleanup_size end - def self.cleanup_formula(formula) - formula.eligible_kegs_for_cleanup.each do |keg| - cleanup_path(keg) { keg.uninstall } - end + def unremovable_kegs + @unremovable_kegs ||= [] + end + + def cleanup_cellar(formulae = Formula.installed) + formulae.each(&method(:cleanup_formula)) + end + + def cleanup_formula(formula) + formula.eligible_kegs_for_cleanup.each(&method(:cleanup_keg)) end - def self.cleanup_logs + def cleanup_keg(keg) + cleanup_path(keg) { keg.uninstall } + rescue Errno::EACCES => e + opoo e.message + unremovable_kegs << keg + end + + def cleanup_logs return unless HOMEBREW_LOGS.directory? HOMEBREW_LOGS.subdirs.each do |dir| cleanup_path(dir) { dir.rmtree } if prune?(dir, days_default: 14) end end - def self.cleanup_cellar - Formula.installed.each do |formula| - cleanup_formula formula - end - end - - def self.cleanup_cache(cache = HOMEBREW_CACHE) + def cleanup_cache(cache = HOMEBREW_CACHE) return unless cache.directory? cache.children.each do |path| if path.to_s.end_with? ".incomplete" @@ -97,7 +106,7 @@ module Homebrew end end - def self.cleanup_path(path) + def cleanup_path(path) if ARGV.dry_run? puts "Would remove: #{path} (#{path.abv})" else @@ -108,7 +117,7 @@ module Homebrew update_disk_cleanup_size(path.disk_usage) end - def self.cleanup_lockfiles + def cleanup_lockfiles return unless HOMEBREW_LOCK_DIR.directory? candidates = HOMEBREW_LOCK_DIR.children lockfiles = candidates.select(&:file?) @@ -118,7 +127,7 @@ module Homebrew end end - def self.rm_ds_store + def rm_ds_store paths = Queue.new %w[Cellar Frameworks Library bin etc include lib opt sbin share var] .map { |p| HOMEBREW_PREFIX/p }.each { |p| paths << p if p.exist? } @@ -136,7 +145,7 @@ module Homebrew workers.map(&:join) end - def self.prune?(path, options = {}) + def prune?(path, options = {}) @time ||= Time.now path_modified_time = path.mtime diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb index 126309579..d8f669e85 100644 --- a/Library/Homebrew/cmd/cleanup.rb +++ b/Library/Homebrew/cmd/cleanup.rb @@ -21,11 +21,14 @@ module Homebrew if ARGV.named.empty? Cleanup.cleanup else - ARGV.resolved_formulae.each { |f| Cleanup.cleanup_formula f } + Cleanup.cleanup_cellar(ARGV.resolved_formulae) end - return if Cleanup.disk_cleanup_size.zero? + report_disk_usage unless Cleanup.disk_cleanup_size.zero? + report_unremovable_kegs unless Cleanup.unremovable_kegs.empty? + end + def report_disk_usage disk_space = disk_usage_readable(Cleanup.disk_cleanup_size) if ARGV.dry_run? ohai "This operation would free approximately #{disk_space} of disk space." @@ -33,4 +36,11 @@ module Homebrew ohai "This operation has freed approximately #{disk_space} of disk space." end end + + def report_unremovable_kegs + ofail <<-EOS.undent + Could not cleanup old kegs! Fix your permissions on: + #{Cleanup.unremovable_kegs.join "\n "} + EOS + end end diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 820a27e31..006c63746 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -8,14 +8,14 @@ #: If `-v` is passed, do a verbose VCS checkout, if the URL represents a VCS. #: This is useful for seeing if an existing VCS cache has been updated. #: -#: If `--force` is passed, remove a previously cached version and re-fetch. +#: If `--force` (or `-f`) is passed, remove a previously cached version and re-fetch. #: #: If `--retry` is passed, retry if a download fails or re-download if the #: checksum of a previously cached version no longer matches. #: #: If `--deps` is passed, also download dependencies for any listed <formulae>. #: -#: If `--build-from-source` is passed, download the source rather than a +#: If `--build-from-source` (or `-s`) is passed, download the source rather than a #: bottle. #: #: If `--force-bottle` is passed, download a bottle if it exists for the diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index e54286f09..1808c4d9c 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -4,7 +4,7 @@ #: <formula> is usually the name of the formula to install, but it can be specified #: in several different ways. See [SPECIFYING FORMULAE][]. #: -#: If `--debug` is passed and brewing fails, open an interactive debugging +#: If `--debug` (or `-d`) is passed and brewing fails, open an interactive debugging #: session with access to IRB or a shell inside the temporary build directory. #: #: If `--env=std` is passed, use the standard build environment instead of superenv. @@ -24,7 +24,7 @@ #: `gcc-4.2` for Apple's GCC 4.2, or `gcc-4.9` for a Homebrew-provided GCC #: 4.9. #: -#: If `--build-from-source` or `-s` is passed, compile the specified <formula> from +#: If `--build-from-source` (or `-s`) is passed, compile the specified <formula> from #: source even if a bottle is provided. Dependencies will still be installed #: from bottles if they are available. #: @@ -48,11 +48,12 @@ #: during installation. #: #: * `install` `--interactive` [`--git`] <formula>: -#: Download and patch <formula>, then open a shell. This allows the user to -#: run `./configure --help` and otherwise determine how to turn the software -#: package into a Homebrew formula. +#: If `--interactive` (or `-i`) is passed, download and patch <formula>, then +#: open a shell. This allows the user to run `./configure --help` and +#: otherwise determine how to turn the software package into a Homebrew +#: formula. #: -#: If `--git` is passed, Homebrew will create a Git repository, useful for +#: If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for #: creating patches to the software. require "missing_formula" @@ -193,13 +194,18 @@ module Homebrew next unless f.opt_prefix.directory? keg = Keg.new(f.opt_prefix.resolved_path) tab = Tab.for_keg(keg) - tab.installed_on_request = true - tab.write + unless tab.installed_on_request + tab.installed_on_request = true + tab.write + end end perform_preinstall_checks - formulae.each { |f| install_formula(f) } + formulae.each do |f| + Migrator.migrate_if_needed(f) + install_formula(f) + end rescue FormulaClassUnavailableError => e # Need to rescue before `FormulaUnavailableError` (superclass of this) # is handled, as searching for a formula doesn't make sense here (the diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb index 293f09eef..5ce6bea48 100644 --- a/Library/Homebrew/cmd/link.rb +++ b/Library/Homebrew/cmd/link.rb @@ -10,7 +10,7 @@ #: be linked or which would be deleted by `brew link --overwrite`, but will not #: actually link or delete any files. #: -#: If `--force` is passed, Homebrew will allow keg-only formulae to be linked. +#: If `--force` (or `-f`) is passed, Homebrew will allow keg-only formulae to be linked. require "ostruct" @@ -86,8 +86,8 @@ module Homebrew opt = HOMEBREW_PREFIX/"opt/#{keg.name}" puts "\nIf you need to have this software first in your PATH instead consider running:" - puts " #{Utils::Shell.prepend_path_in_shell_profile(opt)}/bin" if bin.directory? - puts " #{Utils::Shell.prepend_path_in_shell_profile(opt)}/sbin" if sbin.directory? + puts " #{Utils::Shell.prepend_path_in_shell_profile(opt/"bin")}" if bin.directory? + puts " #{Utils::Shell.prepend_path_in_shell_profile(opt/"sbin")}" if sbin.directory? end def keg_only?(rack) diff --git a/Library/Homebrew/cmd/migrate.rb b/Library/Homebrew/cmd/migrate.rb index 2726b1480..951a2942e 100644 --- a/Library/Homebrew/cmd/migrate.rb +++ b/Library/Homebrew/cmd/migrate.rb @@ -2,7 +2,7 @@ #: Migrate renamed packages to new name, where <formulae> are old names of #: packages. #: -#: If `--force` is passed, then treat installed <formulae> and passed <formulae> +#: If `--force` (or `-f`) is passed, then treat installed <formulae> and passed <formulae> #: like if they are from same taps and migrate them anyway. require "migrator" diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index a18f4e399..f163212e1 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -7,7 +7,7 @@ #: If `--quiet` is passed, list only the names of outdated brews (takes #: precedence over `--verbose`). #: -#: If `--verbose` is passed, display detailed version information. +#: If `--verbose` (or `-v`) is passed, display detailed version information. #: #: If `--json=`<version> is passed, the output will be in JSON format. The only #: valid version is `v1`. @@ -64,7 +64,9 @@ module Homebrew "#{full_name} (#{kegs.map(&:version).join(", ")})" end.join(", ") - puts "#{outdated_versions} < #{current_version}" + pinned_version = " [pinned at #{f.pinned_version}]" if f.pinned? + + puts "#{outdated_versions} < #{current_version}#{pinned_version}" else puts f.full_installed_specified_name end @@ -86,7 +88,9 @@ module Homebrew json << { name: f.full_name, installed_versions: outdated_versions.collect(&:to_s), - current_version: current_version } + current_version: current_version, + pinned: f.pinned?, + pinned_version: f.pinned_version } end puts JSON.generate(json) diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 586405909..c625d2d97 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -15,6 +15,7 @@ module Homebrew onoe "#{f.full_name} is pinned. You must unpin it to reinstall." next end + Migrator.migrate_if_needed(f) reinstall_formula(f) end end diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index 5d02ebd1e..9c51a0d1c 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -1,7 +1,7 @@ #: * `uninstall`, `rm`, `remove` [`--force`] [`--ignore-dependencies`] <formula>: #: Uninstall <formula>. #: -#: If `--force` is passed, and there are multiple versions of <formula> +#: If `--force` (or `-f`) is passed, and there are multiple versions of <formula> #: installed, delete all installed versions. #: #: If `--ignore-dependencies` is passed, uninstalling won't fail, even if diff --git a/Library/Homebrew/cmd/unpack.rb b/Library/Homebrew/cmd/unpack.rb index 60d796d9f..89992e1f0 100644 --- a/Library/Homebrew/cmd/unpack.rb +++ b/Library/Homebrew/cmd/unpack.rb @@ -6,7 +6,7 @@ #: If `--patch` is passed, patches for <formulae> will be applied to the #: unpacked source. #: -#: If `--git` is passed, a Git repository will be initialized in the unpacked +#: If `--git` (or `-g`) is passed, a Git repository will be initialized in the unpacked #: source. This is useful for creating patches for the software. require "stringio" diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 4002df75c..a6936c78c 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -502,12 +502,18 @@ class Reporter end def migrate_formula_rename - Formula.installed.map(&:oldname).compact.each do |old_name| - old_name_dir = HOMEBREW_CELLAR/old_name - next if old_name_dir.symlink? - next unless old_name_dir.directory? && !old_name_dir.subdirs.empty? + Formula.installed.each do |formula| + next unless Migrator.needs_migration?(formula) - new_name = tap.formula_renames[old_name] + oldname = formula.oldname + oldname_rack = HOMEBREW_CELLAR/oldname + + if oldname_rack.subdirs.empty? + oldname_rack.rmdir_if_possible + next + end + + new_name = tap.formula_renames[oldname] next unless new_name new_full_name = "#{tap}/#{new_name}" @@ -519,13 +525,7 @@ class Reporter next end - begin - migrator = Migrator.new(f) - migrator.migrate - rescue Migrator::MigratorDifferentTapsError - rescue Exception => e - onoe e - end + Migrator.migrate_if_needed(f) end end diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 5cfdb3f46..197a99f2e 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -5,7 +5,7 @@ #: If `--merge` is specified then `git merge` is used to include updates #: (rather than `git rebase`). #: -#: If `--force` is specified then always do a slower, full update check even +#: If `--force` (or `-f`) is specified then always do a slower, full update check even #: if unnecessary. # Hide shellcheck complaint: diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index ed36b8f33..d007ff8c8 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -88,6 +88,7 @@ module Homebrew end formulae_to_install.each do |f| + Migrator.migrate_if_needed(f) upgrade_formula(f) next unless ARGV.include?("--cleanup") next unless f.installed? diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 0fc26656a..1a4bb24a1 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -331,25 +331,33 @@ class FormulaAuditor problem "File should end with a newline" unless text.trailing_newline? - versioned_formulae = Dir[formula.path.to_s.gsub(/\.rb$/, "@*.rb")] - needs_versioned_alias = !versioned_formulae.empty? && - formula.tap && - formula.aliases.grep(/.@\d/).empty? - if needs_versioned_alias - _, last_alias_version = File.basename(versioned_formulae.sort.reverse.first) - .gsub(/\.rb$/, "") - .split("@") - major, minor, = formula.version.to_s.split(".") - alias_name = if last_alias_version.split(".").length == 1 - "#{formula.name}@#{major}" - else - "#{formula.name}@#{major}.#{minor}" + if formula.versioned_formula? + unversioned_formula = Pathname.new formula.path.to_s.gsub(/@.*\.rb$/, ".rb") + unless unversioned_formula.exist? + unversioned_name = unversioned_formula.basename(".rb") + problem "#{formula} is versioned but no #{unversioned_name} formula exists" + end + else + versioned_formulae = Dir[formula.path.to_s.gsub(/\.rb$/, "@*.rb")] + needs_versioned_alias = !versioned_formulae.empty? && + formula.tap && + formula.aliases.grep(/.@\d/).empty? + if needs_versioned_alias + _, last_alias_version = File.basename(versioned_formulae.sort.reverse.first) + .gsub(/\.rb$/, "") + .split("@") + major, minor, = formula.version.to_s.split(".") + alias_name = if last_alias_version.split(".").length == 1 + "#{formula.name}@#{major}" + else + "#{formula.name}@#{major}.#{minor}" + end + problem <<-EOS.undent + Formula has other versions so create an alias: + cd #{formula.tap.alias_dir} + ln -s #{formula.path.to_s.gsub(formula.tap.path, "..")} #{alias_name} + EOS end - problem <<-EOS.undent - Formula has other versions so create an alias: - cd #{formula.tap.alias_dir} - ln -s #{formula.path.to_s.gsub(formula.tap.path, "..")} #{alias_name} - EOS end return unless @strict @@ -1185,6 +1193,10 @@ class FormulaAuditor problem "'fails_with :llvm' is now a no-op so should be removed" end + if line =~ /system\s+['"](otool|install_name_tool|lipo)/ && formula.name != "cctools" + problem "Use ruby-macho instead of calling #{$1}" + end + if formula.tap.to_s == "homebrew/core" ["OS.mac?", "OS.linux?"].each do |check| next unless line.include?(check) diff --git a/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb b/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb deleted file mode 100644 index 7531ef9cf..000000000 --- a/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb +++ /dev/null @@ -1,166 +0,0 @@ -#: @hide_from_man_page -#: * `boneyard-formula-pr` [`--dry-run`] [`--local`] [`--reason=<reason>`] <formula> : -#: Creates a pull request to boneyard a formula. -#: -#: If `--dry-run` is passed, print what would be done rather than doing it. -#: -#: If `--local` is passed, perform only local operations (i.e. don't push or create PR). -#: -#: If `--reason=<reason>` is passed, append this to the commit/PR message. - -require "formula" -require "json" -require "fileutils" - -begin - require "json" -rescue LoadError - puts "Homebrew does not provide Ruby dependencies; install with:" - puts " gem install json" - odie "Dependency json is not installed." -end - -module Homebrew - module_function - - def boneyard_formula_pr - local_only = ARGV.include?("--local") - formula = ARGV.formulae.first - reason = ARGV.value("reason") - odie "No formula found!" unless formula - - formula_relpath = formula.path.relative_path_from(formula.tap.path) - formula_file = "#{formula.name}.rb" - bottle_block = File.read(formula.path).include? " bottle do" - boneyard_tap = Tap.fetch("homebrew", "boneyard") - tap_migrations_path = formula.tap.path/"tap_migrations.json" - if ARGV.dry_run? - ohai "brew update" - ohai "brew tap #{boneyard_tap.name}" - ohai "cd #{formula.tap.path}" - cd formula.tap.path - ohai "cp #{formula_relpath} #{boneyard_tap.path}" - ohai "git rm #{formula_relpath}" - unless File.exist? tap_migrations_path - ohai "Creating tap_migrations.json for #{formula.tap.name}" - ohai "git add #{tap_migrations_path}" - end - ohai "Loading tap_migrations.json" - ohai "Adding #{formula.name} to tap_migrations.json" - else - safe_system HOMEBREW_BREW_FILE, "update" - safe_system HOMEBREW_BREW_FILE, "tap", boneyard_tap.name - cd formula.tap.path - cp formula_relpath, boneyard_tap.formula_dir - safe_system "git", "rm", formula_relpath - unless File.exist? tap_migrations_path - tap_migrations_path.write <<-EOS.undent - { - } - EOS - safe_system "git", "add", tap_migrations_path - end - tap_migrations = JSON.parse(File.read(tap_migrations_path)) - tap_migrations[formula.name] = boneyard_tap.name - tap_migrations = tap_migrations.sort.inject({}) { |acc, elem| acc.merge!(elem[0] => elem[1]) } - tap_migrations_path.atomic_write(JSON.pretty_generate(tap_migrations) + "\n") - end - unless which("hub") || local_only - if ARGV.dry_run? - ohai "brew install hub" - else - safe_system HOMEBREW_BREW_FILE, "install", "hub" - end - end - branch = "#{formula.name}-boneyard" - - reason = " because #{reason}" if reason - - if ARGV.dry_run? - ohai "cd #{formula.tap.path}" - ohai "git checkout --no-track -b #{branch} origin/master" - ohai "git commit --no-edit --verbose --message=\"#{formula.name}: migrate to boneyard\" -- #{formula_relpath} #{tap_migrations_path.basename}" - - unless local_only - ohai "hub fork --no-remote" - ohai "hub fork" - ohai "hub fork (to read $HUB_REMOTE)" - ohai "git push $HUB_REMOTE #{branch}:#{branch}" - ohai "hub pull-request -m $'#{formula.name}: migrate to boneyard\\n\\nCreated with `brew boneyard-formula-pr`#{reason}.'" - end - - ohai "git checkout -" - else - cd formula.tap.path - safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master" - safe_system "git", "commit", "--no-edit", "--verbose", - "--message=#{formula.name}: migrate to boneyard", - "--", formula_relpath, tap_migrations_path.basename - - unless local_only - safe_system "hub", "fork", "--no-remote" - quiet_system "hub", "fork" - remote = Utils.popen_read("hub fork 2>&1")[/fatal: remote (.+) already exists\./, 1] - odie "cannot get remote from 'hub'!" unless remote - safe_system "git", "push", remote, "#{branch}:#{branch}" - pr_message = <<-EOS.undent - #{formula.name}: migrate to boneyard - - Created with `brew boneyard-formula-pr`#{reason}. - EOS - pr_url = Utils.popen_read("hub", "pull-request", "-m", pr_message).chomp - end - - safe_system "git", "checkout", "-" - end - - if ARGV.dry_run? - ohai "cd #{boneyard_tap.path}" - ohai "git checkout --no-track -b #{branch} origin/master" - if bottle_block - ohai "Removing bottle block" - else - ohai "No bottle block to remove" - end - ohai "git add #{formula_file}" - ohai "git commit --no-edit --verbose --message=\"#{formula.name}: migrate from #{formula.tap.repo}\" -- #{formula_file}" - - unless local_only - ohai "hub fork --no-remote" - ohai "hub fork" - ohai "hub fork (to read $HUB_REMOTE)" - ohai "git push $HUB_REMOTE #{branch}:#{branch}" - ohai "hub pull-request --browse -m $'#{formula.name}: migrate from #{formula.tap.repo}\\n\\nGoes together with $PR_URL\\n\\nCreated with `brew boneyard-formula-pr`#{reason}.'" - end - - ohai "git checkout -" - else - cd boneyard_tap.formula_dir - safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master" - if bottle_block - Utils::Inreplace.inreplace formula_file, / bottle do.+?end\n\n/m, "" - end - safe_system "git", "add", formula_file - safe_system "git", "commit", "--no-edit", "--verbose", - "--message=#{formula.name}: migrate from #{formula.tap.repo}", - "--", formula_file - - unless local_only - safe_system "hub", "fork", "--no-remote" - quiet_system "hub", "fork" - remote = Utils.popen_read("hub fork 2>&1")[/fatal: remote (.+) already exists\./, 1] - odie "cannot get remote from 'hub'!" unless remote - safe_system "git", "push", remote, "#{branch}:#{branch}" - safe_system "hub", "pull-request", "--browse", "-m", <<-EOS.undent - #{formula.name}: migrate from #{formula.tap.repo} - - Goes together with #{pr_url}. - - Created with `brew boneyard-formula-pr`#{reason}. - EOS - end - - safe_system "git", "checkout", "-" - end - end -end diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index b11da5607..8d3038a5a 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -6,7 +6,7 @@ #: generated DSL. Passing `--keep-old` will attempt to keep it at its #: original value, while `--no-rebuild` will remove it. #: -#: If `--verbose` is passed, print the bottling commands and any warnings +#: If `--verbose` (or `-v`) is passed, print the bottling commands and any warnings #: encountered. #: #: If `--skip-relocation` is passed, do not check if the bottle can be marked diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb index a146f23a8..4e5103910 100644 --- a/Library/Homebrew/dev-cmd/man.rb +++ b/Library/Homebrew/dev-cmd/man.rb @@ -106,7 +106,9 @@ module Homebrew Utils.popen(["ronn", format_flag] + shared_args, "rb+") do |ronn| ronn.write markup ronn.close_write - target.atomic_write ronn.read + ronn_output = ronn.read + ronn_output.gsub!(%r{</?var>}, "`") if format_flag == "--markdown" + target.atomic_write ronn_output end end diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index 4898629b0..288aa8a87 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -7,7 +7,7 @@ #: To test the development or head version of a formula, use `--devel` or #: `--HEAD`. #: -#: If `--debug` is passed and the test fails, an interactive debugger will be +#: If `--debug` (or `-d`) is passed and the test fails, an interactive debugger will be #: launched with access to IRB or a shell inside the temporary test directory. #: #: If `--keep-tmp` is passed, the temporary files created for the test are diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 18e7d96f2..91c7d880b 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -3,7 +3,7 @@ #: `--only=`<test_script> runs only <test_script>_spec.rb, and `--seed` #: randomizes tests with the provided value instead of a random seed. #: -#: If `--verbose` is passed, print the command that runs the tests. +#: If `--verbose` (or `-v`) is passed, print the command that runs the tests. #: #: If `--coverage` is passed, also generate code coverage reports. #: diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb index 2ff168669..add05bc7c 100644 --- a/Library/Homebrew/dev-cmd/update-test.rb +++ b/Library/Homebrew/dev-cmd/update-test.rb @@ -33,12 +33,24 @@ module Homebrew elsif date = ARGV.value("before") Utils.popen_read("git", "rev-list", "-n1", "--before=#{date}", "origin/master").chomp elsif ARGV.include?("--to-tag") - Utils.popen_read("git", "tag", "--list", "--sort=-version:refname").lines[1].chomp + previous_tag = + Utils.popen_read("git", "tag", "--list", "--sort=-version:refname").lines[1] + unless previous_tag + safe_system "git", "fetch", "--tags", "--depth=1" + previous_tag = + Utils.popen_read("git", "tag", "--list", "--sort=-version:refname").lines[1] + end + previous_tag.to_s.chomp else Utils.popen_read("git", "rev-parse", "origin/master").chomp end + odie "Could not find start commit!" if start_commit.empty? + start_commit = Utils.popen_read("git", "rev-parse", start_commit).chomp + odie "Could not find start commit!" if start_commit.empty? + end_commit = Utils.popen_read("git", "rev-parse", "HEAD").chomp + odie "Could not find end commit!" if end_commit.empty? puts "Start commit: #{start_commit}" puts "End commit: #{end_commit}" diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index c8c4b83d2..61cdf2f1a 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -753,13 +753,14 @@ module Homebrew def check_git_version # https://help.github.com/articles/https-cloning-errors return unless Utils.git_available? - return unless Version.create(Utils.git_version) < Version.create("1.7.10") + return unless Version.create(Utils.git_version) < Version.create("1.8.5") git = Formula["git"] git_upgrade_cmd = git.any_version_installed? ? "upgrade" : "install" <<-EOS.undent An outdated version (#{Utils.git_version}) of Git was detected in your PATH. - Git 1.7.10 or newer is required to perform checkouts over HTTPS from GitHub. + Git 1.8.5 or newer is required to perform checkouts over HTTPS from GitHub and + to support the 'git -C <path>' option. Please upgrade: brew #{git_upgrade_cmd} git EOS @@ -794,31 +795,59 @@ module Homebrew EOS end - def check_git_origin + def check_brew_git_origin return if !Utils.git_available? || !(HOMEBREW_REPOSITORY/".git").exist? origin = HOMEBREW_REPOSITORY.git_origin if origin.nil? <<-EOS.undent - Missing git origin remote. + Missing Homebrew/brew git origin remote. Without a correctly configured origin, Homebrew won't update properly. You can solve this by adding the Homebrew remote: - cd #{HOMEBREW_REPOSITORY} - git remote add origin #{Formatter.url("https://github.com/Homebrew/brew.git")} + git -C "#{HOMEBREW_REPOSITORY}" remote add origin #{Formatter.url("https://github.com/Homebrew/brew.git")} EOS - elsif origin !~ %r{Homebrew/brew(\.git)?$} + elsif origin !~ %r{Homebrew/brew(\.git|/)?$} <<-EOS.undent - Suspicious git origin remote found. + Suspicious Homebrew/brew git origin remote found. With a non-standard origin, Homebrew won't pull updates from the main repository. The current git origin is: #{origin} Unless you have compelling reasons, consider setting the - origin remote to point at the main repository, located at: - #{Formatter.url("https://github.com/Homebrew/brew.git")} + origin remote to point at the main repository by running: + git -C "#{HOMEBREW_REPOSITORY}" remote add origin #{Formatter.url("https://github.com/Homebrew/brew.git")} + EOS + end + end + + def check_coretap_git_origin + coretap_path = CoreTap.instance.path + return if !Utils.git_available? || !(coretap_path/".git").exist? + + origin = coretap_path.git_origin + + if origin.nil? + <<-EOS.undent + Missing #{CoreTap.instance} git origin remote. + + Without a correctly configured origin, Homebrew won't update + properly. You can solve this by adding the Homebrew remote: + git -C "#{coretap_path}" remote add origin #{Formatter.url("https://github.com/Homebrew/homebrew-core.git")} + EOS + elsif origin !~ %r{Homebrew/homebrew-core(\.git|/)?$} + <<-EOS.undent + Suspicious #{CoreTap.instance} git origin remote found. + + With a non-standard origin, Homebrew won't pull updates from + the main repository. The current git origin is: + #{origin} + + Unless you have compelling reasons, consider setting the + origin remote to point at the main repository by running: + git -C "#{coretap_path}" remote add origin #{Formatter.url("https://github.com/Homebrew/homebrew-core.git")} EOS end end diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 77da4489e..cfdf5e12d 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -363,14 +363,6 @@ class BuildError < RuntimeError end end - if formula.tap && formula.tap.name == "homebrew/boneyard" - onoe <<-EOS.undent - #{formula} was moved to homebrew-boneyard because it has unfixable issues. - Please do not file any issues about this. Sorry! - EOS - return - end - if formula.tap && defined?(OS::ISSUES_URL) if formula.tap.official? puts Formatter.error(Formatter.url(OS::ISSUES_URL), label: "READ THIS") diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 443619206..523de244d 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -252,12 +252,14 @@ class Formula public - # The alias path that was used to install this formula, if present. + # The alias path that was used to install this formula, if it exists. # Can differ from alias_path, which is the alias used to find the formula, # and is specified to this instance. def installed_alias_path path = build.source["path"] if build.is_a?(Tab) - path if path =~ %r{#{HOMEBREW_TAP_DIR_REGEX}/Aliases} + return unless path =~ %r{#{HOMEBREW_TAP_DIR_REGEX}/Aliases} + return unless File.symlink?(path) + path end def installed_alias_name @@ -1555,6 +1557,8 @@ class Formula hide.include?(d.name) || d.installed_prefixes.empty? end missing_dependencies + rescue FormulaUnavailableError + [] end # @private diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index cb9cd9113..d4b9c5d77 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -240,8 +240,9 @@ class Keg def remove_opt_record opt_record.unlink aliases.each do |a| - next if !opt_record.symlink? && !opt_record.exist? - (opt_record.parent/a).delete + alias_symlink = opt_record.parent/a + next if !alias_symlink.symlink? && !alias_symlink.exist? + alias_symlink.delete end opt_record.parent.rmdir_if_possible end diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 3eb7f833e..3cb6c5178 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -77,13 +77,35 @@ class Migrator # path to newname cellar according to new name attr_reader :new_cellar + # true if new cellar existed at initialization time + attr_reader :new_cellar_existed + # path to newname pin attr_reader :new_pin_record # path to newname keg that will be linked if old_linked_keg isn't nil attr_reader :new_linked_keg_record - def initialize(formula) + def self.needs_migration?(formula) + oldname = formula.oldname + return false unless oldname + oldname_rack = HOMEBREW_CELLAR/oldname + return false if oldname_rack.symlink? + return false unless oldname_rack.directory? + true + end + + def self.migrate_if_needed(formula) + return unless Migrator.needs_migration?(formula) + begin + migrator = Migrator.new(formula) + migrator.migrate + rescue Exception => e + onoe e + end + end + + def initialize(formula, force: ARGV.force?) @oldname = formula.oldname @newname = formula.name raise MigratorNoOldnameError, formula unless oldname @@ -95,11 +117,12 @@ class Migrator @old_tabs = old_cellar.subdirs.map { |d| Tab.for_keg(Keg.new(d)) } @old_tap = old_tabs.first.tap - if !ARGV.force? && !from_same_taps? + if !force && !from_same_tap_user? raise MigratorDifferentTapsError.new(formula, old_tap) end @new_cellar = HOMEBREW_CELLAR/formula.name + @new_cellar_existed = @new_cellar.exist? if @old_linked_keg = linked_old_linked_keg @old_linked_keg_record = old_linked_keg.linked_keg_record if old_linked_keg.linked? @@ -121,15 +144,26 @@ class Migrator end end - def from_same_taps? - if formula.tap == old_tap + def from_same_tap_user? + formula_tap_user = formula.tap.user if formula.tap + old_tap_user = nil + + new_tap = if old_tap + old_tap_user, = old_tap.user + if migrate_tap = old_tap.tap_migrations[formula.oldname] + new_tap_user, new_tap_repo = migrate_tap.split("/") + "#{new_tap_user}/#{new_tap_repo}" + end + end + + if formula_tap_user == old_tap_user true # Homebrew didn't use to update tabs while performing tap-migrations, # so there can be INSTALL_RECEIPT's containing wrong information about tap, # so we check if there is an entry about oldname migrated to tap and if # newname's tap is the same as tap to which oldname migrated, then we # can perform migrations and the taps for oldname and newname are the same. - elsif formula.tap && old_tap && formula.tap == old_tap.tap_migrations[formula.oldname] + elsif formula.tap && old_tap && formula.tap == new_tap fix_tabs true else @@ -138,7 +172,10 @@ class Migrator end def linked_old_linked_keg - kegs = old_cellar.subdirs.map { |d| Keg.new(d) } + keg_dirs = [] + keg_dirs += new_cellar.subdirs if new_cellar.exist? + keg_dirs += old_cellar.subdirs + kegs = keg_dirs.map { |d| Keg.new(d) } kegs.detect(&:linked?) || kegs.detect(&:optlinked?) end @@ -147,47 +184,50 @@ class Migrator end def migrate - if old_cellar.exist? && new_cellar.exist? + oh1 "Migrating #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}" + lock + unlink_oldname + unlink_newname if new_cellar.exist? + repin + move_to_new_directory + link_oldname_cellar + link_oldname_opt + link_newname unless old_linked_keg.nil? + update_tabs + rescue Interrupt + ignore_interrupts { backup_oldname } + rescue Exception => e + onoe "Error occurred while migrating." + puts e + puts e.backtrace if ARGV.debug? + puts "Backing up..." + ignore_interrupts { backup_oldname } + ensure + unlock + end + + # move everything from Cellar/oldname to Cellar/newname + def move_to_new_directory + return unless old_cellar.exist? + + if new_cellar.exist? conflicted = false old_cellar.each_child do |c| - if (new_cellar/c.basename).exist? + next unless (new_cellar/c.basename).exist? + begin + FileUtils.rm_rf c + rescue Errno::EACCES conflicted = true onoe "#{new_cellar/c.basename} already exists." end end + if conflicted - onoe "Remove #{new_cellar} manually and run brew migrate #{oldname}." - return + odie "Remove #{new_cellar} manually and run brew migrate #{oldname}." end end - begin - oh1 "Migrating #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}" - lock - unlink_oldname - unlink_newname if new_cellar.exist? - move_to_new_directory - repin - link_oldname_cellar - link_oldname_opt - link_newname unless old_linked_keg.nil? - update_tabs - rescue Interrupt - ignore_interrupts { backup_oldname } - rescue Exception => e - onoe "Error occurred while migrating." - puts e - puts e.backtrace if ARGV.debug? - puts "Backuping..." - ignore_interrupts { backup_oldname } - ensure - unlock - end - end - - # move everything from Cellar/oldname to Cellar/newname - def move_to_new_directory - puts "Moving to: #{new_cellar}" + oh1 "Moving #{Formatter.identifier(oldname)} children" if new_cellar.exist? FileUtils.mv(old_cellar.children, new_cellar) else @@ -332,7 +372,7 @@ class Migrator new_cellar.subdirs.each do |d| newname_keg = Keg.new(d) newname_keg.unlink - newname_keg.uninstall + newname_keg.uninstall if new_cellar_existed end end diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index 9c1656aa2..5b903b899 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -31,7 +31,7 @@ module Homebrew #{Formatter.url("https://pip.readthedocs.io/en/stable/installing/")} EOS when "pil" then <<-EOS.undent - Instead of PIL, consider `pip install pillow` or `brew install Homebrew/python/pillow`. + Instead of PIL, consider `pip install pillow` or `brew install Homebrew/science/pillow`. EOS when "macruby" then <<-EOS.undent MacRuby is not packaged and is on an indefinite development hiatus. @@ -64,10 +64,6 @@ module Homebrew and then follow the tutorial: #{Formatter.url("https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md")} EOS - when "osmium" then <<-EOS.undent - The creator of Osmium requests that it not be packaged and that people - use the GitHub master branch instead. - EOS when "gfortran" then <<-EOS.undent GNU Fortran is now provided as part of GCC, and can be installed with: brew install gcc @@ -105,10 +101,14 @@ module Homebrew message = nil Tap.each do |old_tap| - new_tap_name = old_tap.tap_migrations[name] - next unless new_tap_name + new_tap = old_tap.tap_migrations[name] + next unless new_tap + + new_tap_user, new_tap_repo, = new_tap.split("/") + new_tap_name = "#{new_tap_user}/#{new_tap_repo}" + message = <<-EOS.undent - It was migrated from #{old_tap} to #{new_tap_name}. + It was migrated from #{old_tap} to #{new_tap}. You can access it again by running: brew tap #{new_tap_name} EOS diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb index c7b96ae64..a7bc4a1d6 100644 --- a/Library/Homebrew/official_taps.rb +++ b/Library/Homebrew/official_taps.rb @@ -1,11 +1,8 @@ OFFICIAL_TAPS = %w[ apache - dupes - fuse nginx php science - tex ].freeze OFFICIAL_CMD_TAPS = { diff --git a/Library/Homebrew/requirements/ruby_requirement.rb b/Library/Homebrew/requirements/ruby_requirement.rb index 327c13170..acc655924 100644 --- a/Library/Homebrew/requirements/ruby_requirement.rb +++ b/Library/Homebrew/requirements/ruby_requirement.rb @@ -11,7 +11,7 @@ class RubyRequirement < Requirement satisfy(build_env: false) { new_enough_ruby } env do - ENV.prepend_path "PATH", new_enough_ruby + ENV.prepend_path "PATH", new_enough_ruby.dirname end def message diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index fd59539df..db4b1c585 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -100,11 +100,14 @@ class Tab < OpenStruct def self.for_keg(keg) path = keg.join(FILENAME) - if path.exist? + tab = if path.exist? from_file(path) else empty end + + tab["tabfile"] = path + tab end # Returns a tab for the named formula's installation, diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index 7872b42a6..7eeabcf49 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -26,8 +26,6 @@ describe Hbc::DSL, :cask do .* Unexpected method 'future_feature' called on Cask unexpected-method-cask\\. .* - https://github.com/caskroom/homebrew-cask/blob/master/doc/reporting_bugs/pre_bug_report.md - .* https://github.com/caskroom/homebrew-cask#reporting-bugs EOS diff --git a/Library/Homebrew/test/cleanup_spec.rb b/Library/Homebrew/test/cleanup_spec.rb index b0e824767..2c3eddb8c 100644 --- a/Library/Homebrew/test/cleanup_spec.rb +++ b/Library/Homebrew/test/cleanup_spec.rb @@ -34,6 +34,39 @@ describe Homebrew::Cleanup do expect(ds_store).to exist end + + context "when it can't remove a keg" do + let(:f1) { Class.new(Testball) { version "0.1" }.new } + let(:f2) { Class.new(Testball) { version "0.2" }.new } + let(:unremovable_kegs) { [] } + + before(:each) do + described_class.instance_variable_set(:@unremovable_kegs, []) + shutup do + [f1, f2].each do |f| + f.brew do + f.install + end + + Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write + end + end + + allow_any_instance_of(Keg) + .to receive(:uninstall) + .and_raise(Errno::EACCES) + end + + it "doesn't remove any kegs" do + shutup { described_class.cleanup_formula f2 } + expect(f1.installed_kegs.size).to eq(2) + end + + it "lists the unremovable kegs" do + shutup { described_class.cleanup_formula f2 } + expect(described_class.unremovable_kegs).to contain_exactly(f1.installed_kegs[0]) + end + end end specify "::cleanup_formula" do diff --git a/Library/Homebrew/test/cmd/link_spec.rb b/Library/Homebrew/test/cmd/link_spec.rb index 7b85c96dc..59ab86cc4 100644 --- a/Library/Homebrew/test/cmd/link_spec.rb +++ b/Library/Homebrew/test/cmd/link_spec.rb @@ -48,9 +48,11 @@ describe "brew link", :integration_test do expect { brew "install", "testball1" }.to be_a_success end - expect { brew "link", "testball1" } + expect { brew "link", "testball1", "SHELL" => "/bin/zsh" } .to output(/testball1 is keg-only/).to_stderr - .and output(/Note that doing so can interfere with building software\./).to_stdout + .and output(a_string_matching(/Note that doing so can interfere with building software\./) + .and(matching("If you need to have this software first in your PATH instead consider running:") + .and(including("echo 'export PATH=\"#{HOMEBREW_PREFIX}/opt/testball1/bin:$PATH\"' >> ~/.zshrc")))).to_stdout .and be_a_success end end diff --git a/Library/Homebrew/test/cmd/outdated_spec.rb b/Library/Homebrew/test/cmd/outdated_spec.rb index 2ce0825e8..65cce27c3 100644 --- a/Library/Homebrew/test/cmd/outdated_spec.rb +++ b/Library/Homebrew/test/cmd/outdated_spec.rb @@ -1,11 +1,87 @@ describe "brew outdated", :integration_test do - it "prints outdated Formulae" do - setup_test_formula "testball" - (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath - - expect { brew "outdated" } - .to output("testball\n").to_stdout - .and not_to_output.to_stderr - .and be_a_success + context "quiet output" do + it "prints outdated Formulae" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + expect { brew "outdated" } + .to output("testball\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + context "verbose output" do + it "prints out the installed and newer versions" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + expect { brew "outdated", "--verbose" } + .to output("testball (0.0.1) < 0.1\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + context "pinned formula, verbose output" do + it "prints out the pinned version" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + shutup do + expect { brew "pin", "testball" }.to be_a_success + end + + expect { brew "outdated", "--verbose" } + .to output("testball (0.0.1) < 0.1 [pinned at 0.0.1]\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + end + + context "json output" do + it "includes pinned version in the json output" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + shutup do + expect { brew "pin", "testball" }.to be_a_success + end + + expected_json = [ + { + name: "testball", + installed_versions: ["0.0.1"], + current_version: "0.1", + pinned: true, + pinned_version: "0.0.1", + }, + ].to_json + + expect { brew "outdated", "--json=v1" } + .to output(expected_json + "\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "has no pinned version when the formula isn't pinned" do + setup_test_formula "testball" + (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath + + expected_json = [ + { + name: "testball", + installed_versions: ["0.0.1"], + current_version: "0.1", + pinned: false, + pinned_version: nil, + }, + ].to_json + + expect { brew "outdated", "--json=v1" } + .to output(expected_json + "\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end end end diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index f5218db73..efe2bf5a2 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -159,6 +159,13 @@ describe FormulaInstaller do it { is_expected.to be false } end + context "it returns false when requirement is satisfied but default formula is installed" do + let(:satisfied?) { true } + let(:satisfied_by_formula?) { false } + let(:installed?) { true } + it { is_expected.to be false } + end + context "it returns true when requirement isn't satisfied" do let(:satisfied?) { false } let(:satisfied_by_formula?) { false } diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 1e064912f..2309c36fb 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -129,6 +129,8 @@ describe Formula do alias_name = "bar" alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}" + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf f.path, alias_path f.build = Tab.new(source: { "path" => alias_path }) @@ -160,6 +162,8 @@ describe Formula do alias_name = "bar" full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}" alias_path = "#{tap.alias_dir}/#{alias_name}" + tap.alias_dir.mkpath + FileUtils.ln_sf f.path, alias_path f.build = Tab.new(source: { "path" => alias_path }) @@ -168,6 +172,8 @@ describe Formula do expect(f.full_installed_alias_name).to eq(full_alias_name) expect(f.installed_specified_name).to eq(alias_name) expect(f.full_installed_specified_name).to eq(full_alias_name) + + FileUtils.rm_rf HOMEBREW_LIBRARY/"Taps/user" end specify "#prefix" do @@ -402,6 +408,8 @@ describe Formula do url "foo-1.0" end f.build = Tab.new(source: { "path" => source_path.to_s }) + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf f.path, source_path expect(f.alias_path).to eq(alias_path) expect(f.installed_alias_path).to eq(source_path.to_s) @@ -443,6 +451,9 @@ describe Formula do allow(described_class).to receive(:installed).and_return(formulae) + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf formula_with_alias.path, alias_path + expect(described_class.installed_with_alias_path(alias_path)) .to eq([formula_with_alias]) end @@ -940,6 +951,9 @@ describe Formula do tab.source["path"] = alias_path stub_formula_loader(f, alias_path) + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf f.path, alias_path + expect(f.current_installed_alias_target).to eq(f) expect(f.latest_formula).to eq(f) expect(f).not_to have_changed_installed_alias_target @@ -952,6 +966,9 @@ describe Formula do tab.source["path"] = alias_path stub_formula_loader(new_formula, alias_path) + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf new_formula.path, alias_path + expect(f.current_installed_alias_target).to eq(new_formula) expect(f.latest_formula).to eq(new_formula) expect(f).to have_changed_installed_alias_target @@ -964,6 +981,9 @@ describe Formula do tab.source["path"] = alias_path stub_formula_loader(new_formula, alias_path) + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf new_formula.path, alias_path + expect(new_formula.current_installed_alias_target).to eq(new_formula) expect(new_formula.latest_formula).to eq(new_formula) expect(new_formula).not_to have_changed_installed_alias_target @@ -1050,6 +1070,10 @@ describe Formula do f.follow_installed_alias = true f.build = setup_tab_for_prefix(same_prefix, path: alias_path) stub_formula_loader(new_formula, alias_path) + + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf new_formula.path, alias_path + expect(f.outdated_kegs).not_to be_empty end @@ -1088,6 +1112,10 @@ describe Formula do tab = setup_tab_for_prefix(old_alias_target_prefix, path: alias_path) old_formula.build = tab allow(described_class).to receive(:installed).and_return([old_formula]) + + CoreTap.instance.alias_dir.mkpath + FileUtils.ln_sf f.path, alias_path + expect(f.outdated_kegs).not_to be_empty end diff --git a/Library/Homebrew/test/missing_formula_spec.rb b/Library/Homebrew/test/missing_formula_spec.rb index f395965a6..215cf17f7 100644 --- a/Library/Homebrew/test/missing_formula_spec.rb +++ b/Library/Homebrew/test/missing_formula_spec.rb @@ -88,14 +88,6 @@ describe Homebrew::MissingFormula do it { is_expected.to be_blacklisted } end - context "osmium" do - %w[osmium Osmium].each do |s| - subject { s } - - it { is_expected.to be_blacklisted } - end - end - context "gfortran" do subject { "gfortran" } diff --git a/Library/Homebrew/test/tab_spec.rb b/Library/Homebrew/test/tab_spec.rb index fec390c28..1b0836c93 100644 --- a/Library/Homebrew/test/tab_spec.rb +++ b/Library/Homebrew/test/tab_spec.rb @@ -258,7 +258,7 @@ describe Tab do it "can create a Tab for a non-existant Keg" do f.prefix.mkpath - expect(subject.tabfile).to be nil + expect(subject.tabfile).to eq(f_tab_path) end end |
