diff options
68 files changed, 721 insertions, 400 deletions
diff --git a/.travis.yml b/.travis.yml index c9ec1e333..0ea85ab9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,13 @@ language: ruby +cache: + directories: + - $HOME/.gem/ruby + - Library/Homebrew/vendor/bundle matrix: include: - os: osx - osx_image: xcode8.1 + osx_image: xcode8.3 rvm: system - os: linux rvm: 2.0.0 diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index aa38b54f4..62cfd79c3 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -23,8 +23,7 @@ end def require?(path) require path rescue LoadError => e - # HACK: ( because we should raise on syntax errors but - # not if the file doesn't exist. TODO make robust! + # we should raise on syntax errors but not if the file doesn't exist. raise unless e.to_s.include? path end diff --git a/Library/Homebrew/build_options.rb b/Library/Homebrew/build_options.rb index d9020ecba..6c6952d71 100644 --- a/Library/Homebrew/build_options.rb +++ b/Library/Homebrew/build_options.rb @@ -47,7 +47,6 @@ class BuildOptions def bottle? include? "build-bottle" end - alias build_bottle? bottle? # True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}. # <pre>args << "--some-new-stuff" if build.head?</pre> diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb index cf5f2b37a..a193a394e 100644 --- a/Library/Homebrew/cask/lib/hbc/cask.rb +++ b/Library/Homebrew/cask/lib/hbc/cask.rb @@ -1,10 +1,12 @@ require "forwardable" require "hbc/dsl" +require "hbc/metadata" module Hbc class Cask extend Forwardable + include Metadata attr_reader :token, :sourcefile_path def initialize(token, sourcefile_path: nil, &block) @@ -20,55 +22,9 @@ module Hbc define_method(method_name) { @dsl.send(method_name) } end - METADATA_SUBDIR = ".metadata".freeze - - def metadata_master_container_path - @metadata_master_container_path ||= caskroom_path.join(METADATA_SUBDIR) - end - - def metadata_versioned_container_path - cask_version = version ? version : :unknown - metadata_master_container_path.join(cask_version.to_s) - end - - def metadata_path(timestamp = :latest, create = false) - if create && timestamp == :latest - raise CaskError, "Cannot create metadata path when timestamp is :latest" - end - path = if timestamp == :latest - Pathname.glob(metadata_versioned_container_path.join("*")).sort.last - elsif timestamp == :now - Utils.nowstamp_metadata_path(metadata_versioned_container_path) - else - metadata_versioned_container_path.join(timestamp) - end - if create - odebug "Creating metadata directory #{path}" - FileUtils.mkdir_p path - end - path - end - - def metadata_subdir(leaf, timestamp = :latest, create = false) - if create && timestamp == :latest - raise CaskError, "Cannot create metadata subdir when timestamp is :latest" - end - unless leaf.respond_to?(:length) && !leaf.empty? - raise CaskError, "Cannot create metadata subdir for empty leaf" - end - parent = metadata_path(timestamp, create) - return nil unless parent.respond_to?(:join) - subdir = parent.join(leaf) - if create - odebug "Creating metadata subdirectory #{subdir}" - FileUtils.mkdir_p subdir - end - subdir - end - def timestamped_versions - Pathname.glob(metadata_master_container_path.join("*", "*")) - .map { |p| p.relative_path_from(metadata_master_container_path) } + Pathname.glob(metadata_timestamped_path(version: "*", timestamp: "*")) + .map { |p| p.relative_path_from(p.parent.parent) } .sort_by(&:basename) # sort by timestamp .map { |p| p.split.map(&:to_s) } end diff --git a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb index b52c43328..c2ed8f462 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb @@ -7,30 +7,10 @@ module Hbc begin cask = CaskLoader.load(cask_token) - installer = Installer.new(cask, - force: force, - skip_cask_deps: skip_cask_deps, - require_sha: require_sha) - installer.print_caveats - installer.fetch - - if cask.installed? - # use copy of cask for uninstallation to avoid 'No such file or directory' bug - installed_cask = cask - - # use the same cask file that was used for installation, if possible - if (installed_caskfile = installed_cask.installed_caskfile).exist? - installed_cask = CaskLoader.load_from_file(installed_caskfile) - end - - # Always force uninstallation, ignore method parameter - Installer.new(installed_cask, force: true).uninstall - end - - installer.stage - installer.install_artifacts - installer.enable_accessibility_access - puts installer.summary + Installer.new(cask, + force: force, + skip_cask_deps: skip_cask_deps, + require_sha: require_sha).reinstall count += 1 rescue CaskUnavailableError => e diff --git a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb index 6887aaf4f..1ee3230ad 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb @@ -12,15 +12,9 @@ module Hbc raise CaskNotInstalledError, cask unless cask.installed? || force - latest_installed_version = cask.timestamped_versions.last - - unless latest_installed_version.nil? - latest_installed_cask_file = cask.metadata_master_container_path - .join(latest_installed_version.join(File::Separator), - "Casks", "#{cask_token}.rb") - + if cask.installed? && !cask.installed_caskfile.nil? # use the same cask file that was used for installation, if possible - cask = CaskLoader.load_from_file(latest_installed_cask_file) if latest_installed_cask_file.exist? + cask = CaskLoader.load_from_file(cask.installed_caskfile) if cask.installed_caskfile.exist? end Installer.new(cask, force: force).uninstall diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb index 824c1b1be..f02f07806 100644 --- a/Library/Homebrew/cask/lib/hbc/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/installer.rb @@ -24,6 +24,7 @@ module Hbc @force = force @skip_cask_deps = skip_cask_deps @require_sha = require_sha + @reinstall = false end def self.print_caveats(cask) @@ -76,13 +77,16 @@ module Hbc def install odebug "Hbc::Installer#install" - if @cask.installed? && !force + if @cask.installed? && !force && !@reinstall raise CaskAlreadyInstalledAutoUpdatesError, @cask if @cask.auto_updates raise CaskAlreadyInstalledError, @cask end print_caveats fetch + uninstall_existing_cask if @reinstall + + oh1 "Installing Cask #{@cask}" stage install_artifacts enable_accessibility_access @@ -90,6 +94,23 @@ module Hbc puts summary end + def reinstall + odebug "Hbc::Installer#reinstall" + @reinstall = true + install + end + + def uninstall_existing_cask + return unless @cask.installed? + + # 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 + + # Always force uninstallation, ignore method parameter + Installer.new(installed_cask, force: true).uninstall + end + def summary s = "" s << "#{Emoji.install_badge} " if Emoji.enabled? @@ -295,19 +316,17 @@ module Hbc end def save_caskfile - unless (old_savedirs = Pathname.glob(@cask.metadata_path("*"))).empty? - old_savedirs.each(&:rmtree) - end + old_savedir = @cask.metadata_timestamped_path return unless @cask.sourcefile_path - savedir = @cask.metadata_subdir("Casks", :now, true) - savedir.mkpath + savedir = @cask.metadata_subdir("Casks", timestamp: :now, create: true) FileUtils.copy @cask.sourcefile_path, savedir + old_savedir.rmtree unless old_savedir.nil? end def uninstall - odebug "Hbc::Installer#uninstall" + oh1 "Uninstalling Cask #{@cask}" disable_accessibility_access uninstall_artifacts purge_versioned_files @@ -355,15 +374,15 @@ module Hbc gain_permissions_remove(@cask.staged_path) if !@cask.staged_path.nil? && @cask.staged_path.exist? # Homebrew-Cask metadata - if @cask.metadata_versioned_container_path.respond_to?(:children) && - @cask.metadata_versioned_container_path.exist? - @cask.metadata_versioned_container_path.children.each do |subdir| + if @cask.metadata_versioned_path.respond_to?(:children) && + @cask.metadata_versioned_path.exist? + @cask.metadata_versioned_path.children.each do |subdir| unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename) gain_permissions_remove(subdir) end end end - @cask.metadata_versioned_container_path.rmdir_if_possible + @cask.metadata_versioned_path.rmdir_if_possible @cask.metadata_master_container_path.rmdir_if_possible # toplevel staged distribution diff --git a/Library/Homebrew/cask/lib/hbc/metadata.rb b/Library/Homebrew/cask/lib/hbc/metadata.rb new file mode 100644 index 000000000..344c38cee --- /dev/null +++ b/Library/Homebrew/cask/lib/hbc/metadata.rb @@ -0,0 +1,73 @@ +module Hbc + module Metadata + METADATA_SUBDIR = ".metadata".freeze + + def metadata_master_container_path + @metadata_master_container_path ||= caskroom_path.join(METADATA_SUBDIR) + end + + def metadata_versioned_path(version: self.version) + cask_version = (version || :unknown).to_s + + if cask_version.empty? + raise CaskError, "Cannot create metadata path with empty version." + end + + metadata_master_container_path.join(cask_version) + end + + def metadata_timestamped_path(version: self.version, timestamp: :latest, create: false) + if create && timestamp == :latest + raise CaskError, "Cannot create metadata path when timestamp is :latest." + end + + path = if timestamp == :latest + Pathname.glob(metadata_versioned_path(version: version).join("*")).sort.last + else + timestamp = new_timestamp if timestamp == :now + metadata_versioned_path(version: version).join(timestamp) + end + + if create && !path.directory? + odebug "Creating metadata directory #{path}." + path.mkpath + end + + path + end + + def metadata_subdir(leaf, version: self.version, timestamp: :latest, create: false) + if create && timestamp == :latest + raise CaskError, "Cannot create metadata subdir when timestamp is :latest." + end + + unless leaf.respond_to?(:empty?) && !leaf.empty? + raise CaskError, "Cannot create metadata subdir for empty leaf." + end + + parent = metadata_timestamped_path(version: version, timestamp: timestamp, create: create) + + return nil if parent.nil? + + subdir = parent.join(leaf) + + if create && !subdir.directory? + odebug "Creating metadata subdirectory #{subdir}." + subdir.mkpath + end + + subdir + end + + private + + def new_timestamp(time = Time.now) + time = time.utc + + timestamp = time.strftime("%Y%m%d%H%M%S") + fraction = format("%.3f", time.to_f - time.to_i)[1..-1] + + timestamp.concat(fraction) + end + end +end diff --git a/Library/Homebrew/cask/lib/hbc/utils.rb b/Library/Homebrew/cask/lib/hbc/utils.rb index ecb565e8e..2a5acbc88 100644 --- a/Library/Homebrew/cask/lib/hbc/utils.rb +++ b/Library/Homebrew/cask/lib/hbc/utils.rb @@ -115,16 +115,5 @@ module Hbc opoo(poo.join(" ") + "\n" + error_message_with_suggestions) end - - def self.nowstamp_metadata_path(container_path) - @timenow ||= Time.now.gmtime - return unless container_path.respond_to?(:join) - - precision = 3 - timestamp = @timenow.strftime("%Y%m%d%H%M%S") - fraction = format("%.#{precision}f", @timenow.to_f - @timenow.to_i)[1..-1] - timestamp.concat(fraction) - container_path.join(timestamp) - end end end diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index 61b703469..b7c0a60c9 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -49,10 +49,10 @@ class Caveats if f.bin.directory? || f.sbin.directory? s << "\nIf you need to have this software first in your PATH run:\n" if f.bin.directory? - s << " #{Utils::Shell.prepend_path_in_shell_profile(f.opt_bin.to_s)}\n" + s << " #{Utils::Shell.prepend_path_in_profile(f.opt_bin.to_s)}\n" end if f.sbin.directory? - s << " #{Utils::Shell.prepend_path_in_shell_profile(f.opt_sbin.to_s)}\n" + s << " #{Utils::Shell.prepend_path_in_profile(f.opt_sbin.to_s)}\n" end end diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 323964dad..90beee89c 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -22,9 +22,9 @@ module Homebrew # legacy behavior shell = :bash unless $stdout.tty? elsif shell_value == "auto" - shell = Utils::Shell.parent_shell || Utils::Shell.preferred_shell + shell = Utils::Shell.parent || Utils::Shell.preferred elsif shell_value - shell = Utils::Shell.path_to_shell(shell_value) + shell = Utils::Shell.from_path(shell_value) end env_keys = build_env_keys(ENV) diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb index 5ce6bea48..b8bd135e0 100644 --- a/Library/Homebrew/cmd/link.rb +++ b/Library/Homebrew/cmd/link.rb @@ -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_profile(opt/"bin")}" if bin.directory? + puts " #{Utils::Shell.prepend_path_in_profile(opt/"sbin")}" if sbin.directory? end def keg_only?(rack) diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index 114c4a8b6..2a07c1b2f 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -63,17 +63,4 @@ module Homebrew def full_clone? ARGV.include?("--full") || ARGV.homebrew_developer? end - - # @deprecated this method will be removed in the future, if no external commands use it. - def install_tap(user, repo, clone_target = nil) - opoo "Homebrew.install_tap is deprecated, use Tap#install." - tap = Tap.fetch(user, repo) - begin - tap.install(clone_target: clone_target, full_clone: full_clone?) - rescue TapAlreadyTappedError - false - else - true - end - end end diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index 92b687725..3c080f616 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -25,3 +25,4 @@ require "compat/tab" require "compat/ENV/shared" require "compat/ENV/std" require "compat/ENV/super" +require "compat/utils/shell" diff --git a/Library/Homebrew/compat/ARGV.rb b/Library/Homebrew/compat/ARGV.rb index 23d02ce1a..e5fa8188f 100644 --- a/Library/Homebrew/compat/ARGV.rb +++ b/Library/Homebrew/compat/ARGV.rb @@ -1,6 +1,6 @@ module HomebrewArgvExtension def build_32_bit? - # odeprecated "ARGV.build_32_bit?" + odeprecated "ARGV.build_32_bit?" include? "--32-bit" end end diff --git a/Library/Homebrew/compat/build_options.rb b/Library/Homebrew/compat/build_options.rb index 52aa9b951..73722dadb 100644 --- a/Library/Homebrew/compat/build_options.rb +++ b/Library/Homebrew/compat/build_options.rb @@ -1,6 +1,11 @@ class BuildOptions def build_32_bit? - # odeprecated "build.build_32_bit?" + odeprecated "build.build_32_bit?" include?("32-bit") && option_defined?("32-bit") end + + def build_bottle? + odeprecated "build.build_bottle?", "build.bottle?" + bottle? + end end diff --git a/Library/Homebrew/compat/dependency_collector.rb b/Library/Homebrew/compat/dependency_collector.rb index bd72c55d4..fbcf1c2a0 100644 --- a/Library/Homebrew/compat/dependency_collector.rb +++ b/Library/Homebrew/compat/dependency_collector.rb @@ -14,7 +14,6 @@ class DependencyCollector output_deprecation(spec, tags) Dependency.new(spec.to_s, tags) when :apr - # TODO: reenable in future when we've fixed a few of the audits. # output_deprecation(spec, tags, "apr-util") Dependency.new("apr-util", tags) when :libltdl diff --git a/Library/Homebrew/compat/global.rb b/Library/Homebrew/compat/global.rb index 797e9ffe5..82c452cc0 100644 --- a/Library/Homebrew/compat/global.rb +++ b/Library/Homebrew/compat/global.rb @@ -3,7 +3,7 @@ module Homebrew def method_missing(method, *args, &block) if instance_methods.include?(method) - # odeprecated "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" + odeprecated "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" return instance_method(method).bind(self).call(*args, &block) end super diff --git a/Library/Homebrew/compat/software_spec.rb b/Library/Homebrew/compat/software_spec.rb index 51b0f3a0b..5efd2aeb4 100644 --- a/Library/Homebrew/compat/software_spec.rb +++ b/Library/Homebrew/compat/software_spec.rb @@ -1,7 +1,5 @@ class BottleSpecification def revision(*args) - # Don't announce deprecation yet as this is quite a big change - # to a public interface. # odeprecated "BottleSpecification.revision", "BottleSpecification.rebuild" rebuild(*args) end diff --git a/Library/Homebrew/compat/tab.rb b/Library/Homebrew/compat/tab.rb index 58fdc4913..2cf71c923 100644 --- a/Library/Homebrew/compat/tab.rb +++ b/Library/Homebrew/compat/tab.rb @@ -1,6 +1,6 @@ class Tab < OpenStruct def build_32_bit? - # odeprecated "Tab.build_32_bit?" + odeprecated "Tab.build_32_bit?" include?("32-bit") end end diff --git a/Library/Homebrew/compat/tap.rb b/Library/Homebrew/compat/tap.rb index d1cf7f1d5..37b1eeac1 100644 --- a/Library/Homebrew/compat/tap.rb +++ b/Library/Homebrew/compat/tap.rb @@ -6,5 +6,3 @@ class Tap core_tap? end end - -CoreFormulaRepository = CoreTap diff --git a/Library/Homebrew/compat/utils.rb b/Library/Homebrew/compat/utils.rb index 56b0824ba..3842e8a83 100644 --- a/Library/Homebrew/compat/utils.rb +++ b/Library/Homebrew/compat/utils.rb @@ -1,18 +1,13 @@ -# return the shell profile file based on users' preference shell def shell_profile - opoo "shell_profile has been deprecated in favor of Utils::Shell.profile" - case ENV["SHELL"] - when %r{/(ba)?sh} then "~/.bash_profile" - when %r{/zsh} then "~/.zshrc" - when %r{/ksh} then "~/.kshrc" - else "~/.bash_profile" - end + # odeprecated "shell_profile", "Utils::Shell.profile" + Utils::Shell.profile end module Tty module_function def white + odeprecated "Tty.white", "Tty.reset.bold" reset.bold end end diff --git a/Library/Homebrew/compat/utils/shell.rb b/Library/Homebrew/compat/utils/shell.rb new file mode 100644 index 000000000..161f10ebb --- /dev/null +++ b/Library/Homebrew/compat/utils/shell.rb @@ -0,0 +1,8 @@ +module Utils + module Shell + def self.shell_profile + odeprecated "Utils::Shell.shell_profile", "Utils::Shell.profile" + Utils::Shell.profile + end + end +end diff --git a/Library/Homebrew/dependable.rb b/Library/Homebrew/dependable.rb index 0834b08ec..785eb94d8 100644 --- a/Library/Homebrew/dependable.rb +++ b/Library/Homebrew/dependable.rb @@ -20,8 +20,6 @@ module Dependable end def required? - # FIXME: Should `required?` really imply `!build?`? And if so, why doesn't - # any of `optional?` and `recommended?` equally imply `!build?`? !build? && !optional? && !recommended? end diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index c9439e207..32130f343 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -743,51 +743,71 @@ class FormulaAuditor return unless formula.tap.git? # git log is required return if @new_formula - fv = FormulaVersions.new(formula, max_depth: 1) + fv = FormulaVersions.new(formula) attributes = [:revision, :version_scheme] - attributes_map = fv.version_attributes_map(attributes, "origin/master") - attributes.each do |attribute| - stable_attribute_map = attributes_map[attribute][:stable] - next if stable_attribute_map.nil? || stable_attribute_map.empty? - - attributes_for_version = stable_attribute_map[formula.version] - next if attributes_for_version.nil? || attributes_for_version.empty? - - old_attribute = formula.send(attribute) - max_attribute = attributes_for_version.max - if max_attribute && old_attribute < max_attribute - problem "#{attribute} should not decrease (from #{max_attribute} to #{old_attribute})" - end - end - + current_version_scheme = formula.version_scheme [:stable, :devel].each do |spec| spec_version_scheme_map = attributes_map[:version_scheme][spec] next if spec_version_scheme_map.nil? || spec_version_scheme_map.empty? - max_version_scheme = spec_version_scheme_map.values.flatten.max + version_schemes = spec_version_scheme_map.values.flatten + max_version_scheme = version_schemes.max max_version = spec_version_scheme_map.select do |_, version_scheme| version_scheme.first == max_version_scheme end.keys.max - formula_spec = formula.send(spec) - next if formula_spec.nil? + if max_version_scheme && current_version_scheme < max_version_scheme + problem "version_scheme should not decrease (from #{max_version_scheme} to #{current_version_scheme})" + end - if max_version && formula_spec.version < max_version - problem "#{spec} version should not decrease (from #{max_version} to #{formula_spec.version})" + if max_version_scheme && current_version_scheme >= max_version_scheme && + current_version_scheme > 1 && + !version_schemes.include?(current_version_scheme - 1) + problem "version_schemes should only increment by 1" end + + formula_spec = formula.send(spec) + next unless formula_spec + + spec_version = formula_spec.version + next unless max_version + next if spec_version >= max_version + + above_max_version_scheme = current_version_scheme > max_version_scheme + map_includes_version = spec_version_scheme_map.keys.include?(spec_version) + next if !current_version_scheme.zero? && + (above_max_version_scheme || map_includes_version) + problem "#{spec} version should not decrease (from #{max_version} to #{spec_version})" end - return if formula.revision.zero? + current_revision = formula.revision if formula.stable - revision_map = attributes_map[:revision][:stable] - stable_revisions = revision_map[formula.stable.version] if revision_map - if !stable_revisions || stable_revisions.empty? - problem "'revision #{formula.revision}' should be removed" + if revision_map = attributes_map[:revision][:stable] + if !revision_map.nil? && !revision_map.empty? + stable_revisions = revision_map[formula.stable.version] + stable_revisions ||= [] + current_revision = formula.revision + max_revision = stable_revisions.max || 0 + + if current_revision < max_revision + problem "revision should not decrease (from #{max_revision} to #{current_revision})" + end + + stable_revisions -= [formula.revision] + if !current_revision.zero? && stable_revisions.empty? && + revision_map.keys.length > 1 + problem "'revision #{formula.revision}' should be removed" + elsif current_revision > 1 && + current_revision != max_revision && + !stable_revisions.include?(current_revision - 1) + problem "revisions should only increment by 1" + end + end end - else # head/devel-only formula - problem "'revision #{formula.revision}' should be removed" + elsif !current_revision.zero? # head/devel-only formula + problem "'revision #{current_revision}' should be removed" end end @@ -1127,6 +1147,10 @@ class FormulaAuditor end end + if line =~ /((revision|version_scheme)\s+0)/ + problem "'#{$1}' should be removed" + end + return unless @strict problem "`#{$1}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ @@ -1344,8 +1368,8 @@ class ResourceAuditor def audit_urls # Check GNU urls; doesn't apply to mirrors - if url =~ %r{^(?:https?|ftp)://(?!alpha).+/gnu/} - problem "Please use \"https://ftpmirror.gnu.org\" instead of #{url}." + if url =~ %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)} + problem "Please use \"https://ftp.gnu.org/gnu/#{$1}\" instead of #{url}." end if mirrors.include?(url) diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index 58a155b13..908f65f8f 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -29,15 +29,6 @@ module Homebrew # Create a formula from a tarball URL def create - # Allow searching MacPorts or Fink. - if ARGV.include? "--macports" - opoo "`brew create --macports` is deprecated; use `brew search --macports` instead" - exec_browser "https://www.macports.org/ports.php?by=name&substr=#{ARGV.next}" - elsif ARGV.include? "--fink" - opoo "`brew create --fink` is deprecated; use `brew search --fink` instead" - exec_browser "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}" - end - raise UsageError if ARGV.named.empty? # Ensure that the cache exists so we can fetch the tarball diff --git a/Library/Homebrew/dev-cmd/mirror.rb b/Library/Homebrew/dev-cmd/mirror.rb index 10811493c..e2492203d 100644 --- a/Library/Homebrew/dev-cmd/mirror.rb +++ b/Library/Homebrew/dev-cmd/mirror.rb @@ -8,10 +8,10 @@ module Homebrew def mirror odie "This command requires at least formula argument!" if ARGV.named.empty? - bintray_user = ENV["BINTRAY_USER"] - bintray_key = ENV["BINTRAY_KEY"] + bintray_user = ENV["HOMEBREW_BINTRAY_USER"] + bintray_key = ENV["HOMEBREW_BINTRAY_KEY"] if !bintray_user || !bintray_key - raise "Missing BINTRAY_USER or BINTRAY_KEY variables!" + raise "Missing HOMEBREW_BINTRAY_USER or HOMEBREW_BINTRAY_KEY variables!" end ARGV.formulae.each do |f| diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb index 36c9ac27c..0616b990b 100644 --- a/Library/Homebrew/dev-cmd/pull.rb +++ b/Library/Homebrew/dev-cmd/pull.rb @@ -263,7 +263,7 @@ module Homebrew end published = [] - bintray_creds = { user: ENV["BINTRAY_USER"], key: ENV["BINTRAY_KEY"] } + bintray_creds = { user: ENV["HOMEBREW_BINTRAY_USER"], key: ENV["HOMEBREW_BINTRAY_KEY"] } if bintray_creds[:user] && bintray_creds[:key] changed_formulae_names.each do |name| f = Formula[name] @@ -272,7 +272,7 @@ module Homebrew published << f.full_name end else - opoo "You must set BINTRAY_USER and BINTRAY_KEY to add or update bottles on Bintray!" + opoo "You must set HOMEBREW_BINTRAY_USER and HOMEBREW_BINTRAY_KEY to add or update bottles on Bintray!" end published end diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 61cdf2f1a..8cca1ba91 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -439,7 +439,7 @@ module Homebrew message = "" - paths.each do |p| + paths(ENV["HOMEBREW_PATH"]).each do |p| case p when "/usr/bin" unless $seen_prefix_bin @@ -460,7 +460,7 @@ module Homebrew Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin occurs before /usr/bin. Here is a one-liner: - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")} EOS end end @@ -480,7 +480,7 @@ module Homebrew <<-EOS.undent Homebrew's bin was not found in your PATH. Consider setting the PATH for example like so - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")} EOS end @@ -495,7 +495,7 @@ module Homebrew Homebrew's sbin was not found in your PATH but you have installed formulae that put executables in #{HOMEBREW_PREFIX}/sbin. Consider setting the PATH for example like so - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/sbin")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/sbin")} EOS end @@ -609,7 +609,7 @@ module Homebrew /Applications/Server.app/Contents/ServerRoot/usr/sbin ].map(&:downcase) - paths.each do |p| + paths(ENV["HOMEBREW_PATH"]).each do |p| next if whitelist.include?(p.downcase) || !File.directory?(p) realpath = Pathname.new(p).realpath.to_s diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 729598e28..283e90b69 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -26,6 +26,13 @@ module EnvActivation ensure replace(old_env) end + + def clear_sensitive_environment! + ENV.keys.each do |key| + next unless /(cookie|key|token)/i =~ key + ENV.delete key + end + end end ENV.extend(EnvActivation) diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index 403ea1978..aafc0a451 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -1,7 +1,6 @@ require "hardware" require "extend/ENV/shared" -# TODO: deprecate compiling related codes after it's only used by brew test. # @private module Stdenv include SharedEnvExtension diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index 0935647f5..4d6d96ad3 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -326,9 +326,7 @@ module Superenv def set_x11_env_if_installed end - # This method does nothing in superenv since there's no custom CFLAGS API - # @private - def set_cpu_flags(*_args) + def set_cpu_flags(*) end end diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index fb6b30836..ff936c75a 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -263,7 +263,7 @@ module Homebrew SSL_CERT_DIR support was removed from Apple's curl. If fetching formulae fails you should: unset SSL_CERT_DIR - and remove it from #{Utils::Shell.shell_profile} if present. + and remove it from #{Utils::Shell.profile} if present. EOS end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index eb254c624..c413e9e94 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -331,7 +331,6 @@ class Pathname raise ChecksumMismatchError.new(self, expected, actual) unless expected == actual end - # FIXME: eliminate the places where we rely on this method alias to_str to_s unless method_defined?(:to_str) def cd @@ -365,9 +364,8 @@ class Pathname unless method_defined?(:/) def /(other) - unless other.respond_to?(:to_str) || other.respond_to?(:to_path) - opoo "Pathname#/ called on #{inspect} with #{other.inspect} as an argument" - puts "This behavior is deprecated, please pass either a String or a Pathname" + if !other.respond_to?(:to_str) && !other.respond_to?(:to_path) + odeprecated "Pathname#/ with #{other.class}", "a String or a Pathname" end self + other.to_s end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 523de244d..4ff5d3175 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -13,6 +13,7 @@ require "pkg_version" require "tap" require "keg" require "migrator" +require "extend/ENV" # A formula provides instructions and metadata for Homebrew to install a piece # of software. Every Homebrew formula is a {Formula}. @@ -1013,10 +1014,17 @@ class Formula @prefix_returns_versioned_prefix = true build = self.build self.build = Tab.for_formula(self) + old_tmpdir = ENV["TMPDIR"] old_temp = ENV["TEMP"] old_tmp = ENV["TMP"] + old_path = ENV["HOMEBREW_PATH"] + ENV["TMPDIR"] = ENV["TEMP"] = ENV["TMP"] = HOMEBREW_TEMP + ENV["HOMEBREW_PATH"] = nil + + ENV.clear_sensitive_environment! + with_logging("post_install") do post_install end @@ -1025,6 +1033,7 @@ class Formula ENV["TMPDIR"] = old_tmpdir ENV["TEMP"] = old_temp ENV["TMP"] = old_tmp + ENV["HOMEBREW_PATH"] = old_path @prefix_returns_versioned_prefix = false end @@ -1664,9 +1673,15 @@ class Formula old_temp = ENV["TEMP"] old_tmp = ENV["TMP"] old_term = ENV["TERM"] + old_path = ENV["HOMEBREW_PATH"] + ENV["CURL_HOME"] = old_curl_home || old_home ENV["TMPDIR"] = ENV["TEMP"] = ENV["TMP"] = HOMEBREW_TEMP ENV["TERM"] = "dumb" + ENV["HOMEBREW_PATH"] = nil + + ENV.clear_sensitive_environment! + mktemp("#{name}-test") do |staging| staging.retain! if ARGV.keep_tmp? @testpath = staging.tmpdir @@ -1689,6 +1704,7 @@ class Formula ENV["TEMP"] = old_temp ENV["TMP"] = old_tmp ENV["TERM"] = old_term + ENV["HOMEBREW_PATH"] = old_path @prefix_returns_versioned_prefix = false end @@ -1892,7 +1908,6 @@ class Formula def exec_cmd(cmd, args, out, logfn) ENV["HOMEBREW_CC_LOG_PATH"] = logfn - # TODO: system "xcodebuild" is deprecated, this should be removed soon. ENV.remove_cc_etc if cmd.to_s.start_with? "xcodebuild" # Turn on argument filtering in the superenv compiler wrapper. @@ -1925,17 +1940,24 @@ class Formula mkdir_p env_home old_home = ENV["HOME"] - ENV["HOME"] = env_home old_curl_home = ENV["CURL_HOME"] + old_path = ENV["HOMEBREW_PATH"] + + ENV["HOME"] = env_home ENV["CURL_HOME"] = old_curl_home || old_home + ENV["HOMEBREW_PATH"] = nil + setup_home env_home + ENV.clear_sensitive_environment! + begin yield staging ensure @buildpath = nil ENV["HOME"] = old_home ENV["CURL_HOME"] = old_curl_home + ENV["HOMEBREW_PATH"] = old_path end end end @@ -2396,7 +2418,6 @@ class Formula # version '4.8.1' # end</pre> def fails_with(compiler, &block) - # TODO: deprecate this in future. # odeprecated "fails_with :llvm" if compiler == :llvm specs.each { |spec| spec.fails_with(compiler, &block) } end diff --git a/Library/Homebrew/formula_cellar_checks.rb b/Library/Homebrew/formula_cellar_checks.rb index c4d599296..7f7d77569 100644 --- a/Library/Homebrew/formula_cellar_checks.rb +++ b/Library/Homebrew/formula_cellar_checks.rb @@ -14,7 +14,7 @@ module FormulaCellarChecks <<-EOS.undent #{prefix_bin} is not in your PATH - You can amend this by altering your #{Utils::Shell.shell_profile} file + You can amend this by altering your #{Utils::Shell.profile} file EOS end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 7fed4b24e..2153e7671 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -887,6 +887,6 @@ class FormulaInstaller def puts_requirement_messages return unless @requirement_messages return if @requirement_messages.empty? - puts @requirement_messages + $stderr.puts @requirement_messages end end diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb index 28c2a3be8..f0fbb3aaf 100644 --- a/Library/Homebrew/formula_versions.rb +++ b/Library/Homebrew/formula_versions.rb @@ -7,21 +7,22 @@ class FormulaVersions ErrorDuringExecution, LoadError, MethodDeprecatedError ].freeze + MAX_VERSIONS_DEPTH = 2 + attr_reader :name, :path, :repository, :entry_name - def initialize(formula, options = {}) + def initialize(formula) @name = formula.name @path = formula.path @repository = formula.tap.path @entry_name = @path.relative_path_from(repository).to_s - @max_depth = options[:max_depth] + @current_formula = formula end def rev_list(branch) repository.cd do - depth = 0 Utils.popen_read("git", "rev-list", "--abbrev-commit", "--remove-empty", branch, "--", entry_name) do |io| - yield io.readline.chomp until io.eof? || (@max_depth && (depth += 1) > @max_depth) + yield io.readline.chomp until io.eof? end end end @@ -49,11 +50,15 @@ class FormulaVersions def bottle_version_map(branch) map = Hash.new { |h, k| h[k] = [] } + + versions_seen = 0 rev_list(branch) do |rev| formula_at_revision(rev) do |f| bottle = f.bottle_specification map[f.pkg_version] << bottle.rebuild unless bottle.checksums.empty? + versions_seen = (map.keys + [f.pkg_version]).uniq.length end + return map if versions_seen > MAX_VERSIONS_DEPTH end map end @@ -62,27 +67,35 @@ class FormulaVersions attributes_map = {} return attributes_map if attributes.empty? - attributes.each do |attribute| - attributes_map[attribute] ||= {} - end - + stable_versions_seen = 0 rev_list(branch) do |rev| formula_at_revision(rev) do |f| attributes.each do |attribute| + attributes_map[attribute] ||= {} map = attributes_map[attribute] - if f.stable - map[:stable] ||= {} - map[:stable][f.stable.version] ||= [] - map[:stable][f.stable.version] << f.send(attribute) - end - next unless f.devel - map[:devel] ||= {} - map[:devel][f.devel.version] ||= [] - map[:devel][f.devel.version] << f.send(attribute) + set_attribute_map(map, f, attribute) + + stable_keys_length = (map[:stable].keys + [f.version]).uniq.length + stable_versions_seen = [stable_versions_seen, stable_keys_length].max end end + break if stable_versions_seen > MAX_VERSIONS_DEPTH end attributes_map end + + private + + def set_attribute_map(map, f, attribute) + if f.stable + map[:stable] ||= {} + map[:stable][f.stable.version] ||= [] + map[:stable][f.stable.version] << f.send(attribute) + end + return unless f.devel + map[:devel] ||= {} + map[:devel][f.devel.version] ||= [] + map[:devel][f.devel.version] << f.send(attribute) + end end diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index 391f5b012..6505ca54e 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -53,7 +53,8 @@ HOMEBREW_PULL_OR_COMMIT_URL_REGEX = %r[https://github\.com/([\w-]+)/([\w-]+)?/(? require "compat" unless ARGV.include?("--no-compat") || ENV["HOMEBREW_NO_COMPAT"] -ORIGINAL_PATHS = ENV["PATH"].split(File::PATH_SEPARATOR).map do |p| +ENV["HOMEBREW_PATH"] ||= ENV["PATH"] +ORIGINAL_PATHS = ENV["HOMEBREW_PATH"].split(File::PATH_SEPARATOR).map do |p| begin Pathname.new(p).expand_path rescue @@ -61,7 +62,6 @@ ORIGINAL_PATHS = ENV["PATH"].split(File::PATH_SEPARATOR).map do |p| end end.compact.freeze -# TODO: remove this as soon as it's removed from commands.rb. HOMEBREW_INTERNAL_COMMAND_ALIASES = { "ls" => "list", "homepage" => "home", diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 23c5246ba..0f8e3a4e6 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -53,29 +53,6 @@ module Language quiet_system python, "-c", script end - # deprecated; use system "python", *setup_install_args(prefix) instead - def self.setup_install(python, prefix, *args) - opoo <<-EOS.undent - Language::Python.setup_install is deprecated. - If you are a formula author, please use - system "python", *Language::Python.setup_install_args(prefix) - instead. - EOS - - # force-import setuptools, which monkey-patches distutils, to make - # sure that we always call a setuptools setup.py. trick borrowed from pip: - # https://github.com/pypa/pip/blob/043af83/pip/req/req_install.py#L743-L780 - shim = <<-EOS.undent - import setuptools, tokenize - __file__ = 'setup.py' - exec(compile(getattr(tokenize, 'open', open)(__file__).read() - .replace('\\r\\n', '\\n'), __file__, 'exec')) - EOS - args += %w[--single-version-externally-managed --record=installed.txt] - args << "--prefix=#{prefix}" - system python, "-c", shim, "install", *args - end - def self.setup_install_args(prefix) shim = <<-EOS.undent import setuptools, tokenize diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb index e069e5265..dcb65d9f8 100644 --- a/Library/Homebrew/official_taps.rb +++ b/Library/Homebrew/official_taps.rb @@ -15,3 +15,19 @@ OFFICIAL_CMD_TAPS = { "homebrew/test-bot" => ["test-bot"], "homebrew/services" => ["services"], }.freeze + +DEPRECATED_OFFICIAL_TAPS = %w[ + binary + completions + devel-only + dupes + emacs + fuse + games + gui + head-only + python + tex + versions + x11 +].freeze diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 8934697cb..cac0dcc30 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -128,11 +128,10 @@ module OS end end - # The remaining logic provides a fake Xcode version for CLT-only - # systems. This behavior only exists because Homebrew used to assume - # Xcode.version would always be non-nil. This is deprecated, and will - # be removed in a future version. To remain compatible, guard usage of - # Xcode.version with an Xcode.installed? check. + # The remaining logic provides a fake Xcode version based on the + # installed CLT version. This is useful as they are packaged + # simultaneously so workarounds need to apply to both based on their + # comparable version. case (DevelopmentTools.clang_version.to_f * 10).to_i when 0 then "dunno" when 1..14 then "3.2.2" diff --git a/Library/Homebrew/os/mac/xquartz.rb b/Library/Homebrew/os/mac/xquartz.rb index b82772faf..2fdf0abea 100644 --- a/Library/Homebrew/os/mac/xquartz.rb +++ b/Library/Homebrew/os/mac/xquartz.rb @@ -5,7 +5,6 @@ module OS module XQuartz module_function - # TODO: confirm this path when you have internet DEFAULT_BUNDLE_PATH = Pathname.new("Applications/Utilities/XQuartz.app").freeze FORGE_BUNDLE_ID = "org.macosforge.xquartz.X11".freeze APPLE_BUNDLE_ID = "org.x.X11".freeze diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb index 3dd7075ec..ddac58444 100644 --- a/Library/Homebrew/readall.rb +++ b/Library/Homebrew/readall.rb @@ -24,14 +24,21 @@ module Readall !failed end - def valid_aliases?(alias_dirs) + def valid_aliases?(alias_dir, formula_dir) + return true unless alias_dir.directory? + failed = false - alias_dirs.each do |alias_dir| - next unless alias_dir.directory? - alias_dir.children.each do |f| - next unless f.symlink? - next if f.file? - onoe "Broken alias: #{f}" + alias_dir.each_child do |f| + if !f.symlink? + onoe "Non-symlink alias: #{f}" + failed = true + elsif !f.file? + onoe "Non-file alias: #{f}" + failed = true + end + + if (formula_dir/"#{f.basename}.rb").exist? + onoe "Formula duplicating alias: #{f}" failed = true end end @@ -57,7 +64,7 @@ module Readall def valid_tap?(tap, options = {}) failed = false if options[:aliases] - valid_aliases = valid_aliases?([tap.alias_dir]) + valid_aliases = valid_aliases?(tap.alias_dir, tap.formula_dir) failed = true unless valid_aliases end valid_formulae = valid_formulae?(tap.formula_files) diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index bd8cf20c8..a4bdabdd1 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -161,11 +161,9 @@ class Requirement class << self include BuildEnvironmentDSL - attr_reader :env_proc + attr_reader :env_proc, :build attr_rw :fatal, :default_formula attr_rw :cask, :download - # build is deprecated, use `depends_on <requirement> => :build` instead - attr_rw :build def satisfy(options = {}, &block) @satisfied ||= Requirement::Satisfier.new(options, &block) diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index fb07f6c55..1d2e4bf64 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -117,8 +117,7 @@ class SoftwareSpec def option(name, description = "") opt = PREDEFINED_OPTIONS.fetch(name) do if name.is_a?(Symbol) - opoo "Passing arbitrary symbols to `option` is deprecated: #{name.inspect}" - puts "Symbols are reserved for future use, please pass a string instead" + odeprecated "passing arbitrary symbols (i.e. #{name.inspect}) to `option`" name = name.to_s end unless name.is_a?(String) @@ -172,7 +171,6 @@ class SoftwareSpec end def fails_with(compiler, &block) - # TODO: deprecate this in future. # odeprecated "fails_with :llvm" if compiler == :llvm compiler_failures << CompilerFailure.create(compiler, &block) end diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 99138330b..c3af73c7e 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -201,6 +201,10 @@ class Tap quiet = options.fetch(:quiet, false) requested_remote = options[:clone_target] || default_remote + if official? && DEPRECATED_OFFICIAL_TAPS.include?(repo) + opoo "#{name} was deprecated. This tap is now empty as all its formulae were migrated." + end + if installed? raise TapAlreadyTappedError, name unless full_clone raise TapAlreadyUnshallowError, name unless shallow? diff --git a/Library/Homebrew/test/.bundle/config b/Library/Homebrew/test/.bundle/config index e451829e9..20549341c 100644 --- a/Library/Homebrew/test/.bundle/config +++ b/Library/Homebrew/test/.bundle/config @@ -1,3 +1,4 @@ --- BUNDLE_PATH: "../vendor/bundle" BUNDLE_DISABLE_SHARED_GEMS: "true" +BUNDLE_BIN: "../bin" diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb index 2ab966f82..3736f3c01 100644 --- a/Library/Homebrew/test/cask/cask_spec.rb +++ b/Library/Homebrew/test/cask/cask_spec.rb @@ -85,8 +85,8 @@ describe Hbc::Cask, :cask do it "proposes a versioned metadata directory name for each instance" do cask_token = "local-caffeine" c = Hbc::CaskLoader.load(cask_token) - metadata_path = Hbc.caskroom.join(cask_token, ".metadata", c.version) - expect(c.metadata_versioned_container_path.to_s).to eq(metadata_path.to_s) + metadata_timestamped_path = Hbc.caskroom.join(cask_token, ".metadata", c.version) + expect(c.metadata_versioned_path.to_s).to eq(metadata_timestamped_path.to_s) end end diff --git a/Library/Homebrew/test/cask/cli/install_spec.rb b/Library/Homebrew/test/cask/cli/install_spec.rb index 5a40017e8..219b9522e 100644 --- a/Library/Homebrew/test/cask/cli/install_spec.rb +++ b/Library/Homebrew/test/cask/cli/install_spec.rb @@ -1,4 +1,18 @@ describe Hbc::CLI::Install, :cask do + it "displays the installation progress" do + output = Regexp.new <<-EOS.undent + ==> Downloading file:.*caffeine.zip + ==> Verifying checksum for Cask local-caffeine + ==> Installing Cask local-caffeine + ==> Moving App 'Caffeine.app' to '.*Caffeine.app'. + .*local-caffeine was successfully installed! + EOS + + expect { + Hbc::CLI::Install.run("local-caffeine") + }.to output(output).to_stdout + end + it "allows staging and activation of multiple Casks at once" do shutup do Hbc::CLI::Install.run("local-transmission", "local-caffeine") diff --git a/Library/Homebrew/test/cask/cli/reinstall_spec.rb b/Library/Homebrew/test/cask/cli/reinstall_spec.rb index e573a3470..8885fa199 100644 --- a/Library/Homebrew/test/cask/cli/reinstall_spec.rb +++ b/Library/Homebrew/test/cask/cli/reinstall_spec.rb @@ -1,4 +1,27 @@ describe Hbc::CLI::Reinstall, :cask do + it "displays the reinstallation progress" do + caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") + + shutup do + Hbc::Installer.new(caffeine).install + end + + output = Regexp.new <<-EOS.undent + ==> Downloading file:.*caffeine.zip + Already downloaded: .*local-caffeine--1.2.3.zip + ==> Verifying checksum for Cask local-caffeine + ==> Uninstalling Cask local-caffeine + ==> Removing App '.*Caffeine.app'. + ==> Installing Cask local-caffeine + ==> Moving App 'Caffeine.app' to '.*Caffeine.app'. + .*local-caffeine was successfully installed! + EOS + + expect { + Hbc::CLI::Reinstall.run("local-caffeine") + }.to output(output).to_stdout + end + it "allows reinstalling a Cask" do shutup do Hbc::CLI::Install.run("local-transmission") diff --git a/Library/Homebrew/test/cask/cli/uninstall_spec.rb b/Library/Homebrew/test/cask/cli/uninstall_spec.rb index c03f64c8f..4089c47b4 100644 --- a/Library/Homebrew/test/cask/cli/uninstall_spec.rb +++ b/Library/Homebrew/test/cask/cli/uninstall_spec.rb @@ -1,4 +1,21 @@ describe Hbc::CLI::Uninstall, :cask do + it "displays the uninstallation progress" do + caffeine = Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/local-caffeine.rb") + + shutup do + Hbc::Installer.new(caffeine).install + end + + output = Regexp.new <<-EOS.undent + ==> Uninstalling Cask local-caffeine + ==> Removing App '.*Caffeine.app'. + EOS + + expect { + Hbc::CLI::Uninstall.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") diff --git a/Library/Homebrew/test/cask/installer_spec.rb b/Library/Homebrew/test/cask/installer_spec.rb index 7dd5b2bda..59d61bbdd 100644 --- a/Library/Homebrew/test/cask/installer_spec.rb +++ b/Library/Homebrew/test/cask/installer_spec.rb @@ -336,9 +336,8 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(caffeine).install end - m_path = caffeine.metadata_path(:now, true) - expect(caffeine.metadata_path(:now, false)).to eq(m_path) - expect(caffeine.metadata_path(:latest)).to eq(m_path) + m_path = caffeine.metadata_timestamped_path(timestamp: :now, create: true) + expect(caffeine.metadata_timestamped_path(timestamp: :latest)).to eq(m_path) end it "generates and finds a metadata subdirectory for an installed Cask" do @@ -349,9 +348,8 @@ describe Hbc::Installer, :cask do end subdir_name = "Casks" - m_subdir = caffeine.metadata_subdir(subdir_name, :now, true) - expect(caffeine.metadata_subdir(subdir_name, :now, false)).to eq(m_subdir) - expect(caffeine.metadata_subdir(subdir_name, :latest)).to eq(m_subdir) + m_subdir = caffeine.metadata_subdir(subdir_name, timestamp: :now, create: true) + expect(caffeine.metadata_subdir(subdir_name, timestamp: :latest)).to eq(m_subdir) end end diff --git a/Library/Homebrew/test/cmd/install_spec.rb b/Library/Homebrew/test/cmd/install_spec.rb index c1240a30e..034bdd53f 100644 --- a/Library/Homebrew/test/cmd/install_spec.rb +++ b/Library/Homebrew/test/cmd/install_spec.rb @@ -217,10 +217,9 @@ describe "brew install", :integration_test do depends_on NonFatalRequirement EOS - # FIXME: This should output to STDERR. expect { brew "install", "testball1" } - .to output(/NonFatalRequirement unsatisfied!/).to_stdout - .and not_to_output.to_stderr + .to output(/NonFatalRequirement unsatisfied!/).to_stderr + .and output(/built in/).to_stdout .and be_a_success end @@ -234,10 +233,9 @@ describe "brew install", :integration_test do depends_on FatalRequirement EOS - # FIXME: This should output to STDERR. expect { brew "install", "testball1" } - .to output(/FatalRequirement unsatisfied!/).to_stdout - .and output(/An unsatisfied requirement failed this build./).to_stderr + .to output(/FatalRequirement unsatisfied!/).to_stderr + .and not_to_output.to_stdout .and be_a_failure end end diff --git a/Library/Homebrew/test/compiler_selector_spec.rb b/Library/Homebrew/test/compiler_selector_spec.rb index 0f6f6b5f2..18efbfd42 100644 --- a/Library/Homebrew/test/compiler_selector_spec.rb +++ b/Library/Homebrew/test/compiler_selector_spec.rb @@ -3,7 +3,7 @@ require "software_spec" describe CompilerSelector do subject { described_class.new(software_spec, versions, compilers) } - let(:compilers) { [:clang, :gcc, :llvm, :gnu] } + let(:compilers) { [:clang, :gcc, :gnu] } let(:software_spec) { SoftwareSpec.new } let(:cc) { :clang } let(:versions) do @@ -28,7 +28,6 @@ describe CompilerSelector do describe "#compiler" do it "raises an error if no matching compiler can be found" do software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) software_spec.fails_with(:gcc) software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.7") @@ -45,11 +44,6 @@ describe CompilerSelector do expect(subject.compiler).to eq(:gcc) end - it "returns clang if it fails with llvm" do - software_spec.fails_with(:llvm) - expect(subject.compiler).to eq(:clang) - end - it "returns clang if it fails with gcc" do software_spec.fails_with(:gcc) expect(subject.compiler).to eq(:clang) @@ -68,13 +62,11 @@ describe CompilerSelector do it "returns gcc if it fails with clang and llvm" do software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) expect(subject.compiler).to eq(:gcc) end it "returns clang if it fails with gcc and llvm" do software_spec.fails_with(:gcc) - software_spec.fails_with(:llvm) expect(subject.compiler).to eq(:clang) end @@ -87,7 +79,6 @@ describe CompilerSelector do example "returns a lower version of gcc if it fails with the highest version" do software_spec.fails_with(:clang) software_spec.fails_with(:gcc) - software_spec.fails_with(:llvm) software_spec.fails_with(gcc: "4.8") expect(subject.compiler).to eq("gcc-4.7") end @@ -102,7 +93,6 @@ describe CompilerSelector do allow(versions).to receive(:gcc_build_version).and_return(Version::NULL) software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.7") diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index c0a090b29..9afb7954a 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -5,6 +5,13 @@ RSpec::Matchers.alias_matcher :have_data, :be_data RSpec::Matchers.alias_matcher :have_end, :be_end RSpec::Matchers.alias_matcher :have_trailing_newline, :be_trailing_newline +module Count + def self.increment + @count ||= 0 + @count += 1 + end +end + describe FormulaText do let(:dir) { mktmpdir } @@ -424,4 +431,187 @@ describe FormulaAuditor do .to match('xcodebuild should be passed an explicit "SYMROOT"') end end + + describe "#audit_revision_and_version_scheme" do + let(:origin_tap_path) { Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" } + let(:formula_subpath) { "Formula/foo#{@foo_version}.rb" } + let(:origin_formula_path) { origin_tap_path/formula_subpath } + let(:tap_path) { Tap::TAP_DIRECTORY/"homebrew/homebrew-bar" } + let(:formula_path) { tap_path/formula_subpath } + + before(:each) do + @foo_version = Count.increment + + origin_formula_path.write <<-EOS.undent + class Foo#{@foo_version} < Formula + url "https://example.com/foo-1.0.tar.gz" + revision 2 + version_scheme 1 + end + EOS + + origin_tap_path.mkpath + origin_tap_path.cd do + shutup do + system "git", "init" + system "git", "add", "--all" + system "git", "commit", "-m", "init" + end + end + + tap_path.mkpath + tap_path.cd do + shutup do + system "git", "clone", origin_tap_path, "." + end + end + end + + subject do + fa = described_class.new(Formulary.factory(formula_path)) + fa.audit_revision_and_version_scheme + fa.problems.first + end + + def formula_gsub(before, after = "") + text = formula_path.read + text.gsub! before, after + formula_path.unlink + formula_path.write text + end + + def formula_gsub_commit(before, after = "") + text = origin_formula_path.read + text.gsub!(before, after) + origin_formula_path.unlink + origin_formula_path.write text + + origin_tap_path.cd do + shutup do + system "git", "commit", "-am", "commit" + end + end + + tap_path.cd do + shutup do + system "git", "fetch" + system "git", "reset", "--hard", "origin/master" + end + end + end + + context "revisions" do + context "should not be removed when first committed above 0" do + it { is_expected.to be_nil } + end + + context "should not decrease with the same version" do + before { formula_gsub_commit "revision 2", "revision 1" } + + it { is_expected.to match("revision should not decrease (from 2 to 1)") } + end + + context "should not be removed with the same version" do + before { formula_gsub_commit "revision 2" } + + it { is_expected.to match("revision should not decrease (from 2 to 0)") } + end + + context "should not decrease with the same, uncommitted version" do + before { formula_gsub "revision 2", "revision 1" } + + it { is_expected.to match("revision should not decrease (from 2 to 1)") } + end + + context "should be removed with a newer version" do + before { formula_gsub_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" } + + it { is_expected.to match("'revision 2' should be removed") } + end + + context "should not warn on an newer version revision removal" do + before do + formula_gsub_commit "revision 2", "" + formula_gsub_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" + end + + it { is_expected.to be_nil } + end + + context "should only increment by 1 with an uncommitted version" do + before do + formula_gsub "foo-1.0.tar.gz", "foo-1.1.tar.gz" + formula_gsub "revision 2", "revision 4" + end + + it { is_expected.to match("revisions should only increment by 1") } + end + + context "should not warn on past increment by more than 1" do + before do + formula_gsub_commit "revision 2", "# no revision" + formula_gsub_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" + formula_gsub_commit "# no revision", "revision 3" + end + + it { is_expected.to be_nil } + end + end + + context "version_schemes" do + context "should not decrease with the same version" do + before { formula_gsub_commit "version_scheme 1" } + + it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } + end + + context "should not decrease with a new version" do + before do + formula_gsub_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" + formula_gsub_commit "version_scheme 1", "" + formula_gsub_commit "revision 2", "" + end + + it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } + end + + context "should only increment by 1" do + before do + formula_gsub_commit "version_scheme 1", "# no version_scheme" + formula_gsub_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" + formula_gsub_commit "revision 2", "" + formula_gsub_commit "# no version_scheme", "version_scheme 3" + end + + it { is_expected.to match("version_schemes should only increment by 1") } + end + end + + context "versions" do + context "uncommitted should not decrease" do + before { formula_gsub "foo-1.0.tar.gz", "foo-0.9.tar.gz" } + + it { is_expected.to match("stable version should not decrease (from 1.0 to 0.9)") } + end + + context "committed can decrease" do + before do + formula_gsub_commit "revision 2" + formula_gsub_commit "foo-1.0.tar.gz", "foo-0.9.tar.gz" + end + + it { is_expected.to be_nil } + end + + context "can decrease with version_scheme increased" do + before do + formula_gsub "revision 2" + formula_gsub "foo-1.0.tar.gz", "foo-0.9.tar.gz" + formula_gsub "version_scheme 1", "version_scheme 2" + end + + it { is_expected.to be_nil } + end + end + end end diff --git a/Library/Homebrew/test/diagnostic_spec.rb b/Library/Homebrew/test/diagnostic_spec.rb index c2bcdb9c0..6e2c09268 100644 --- a/Library/Homebrew/test/diagnostic_spec.rb +++ b/Library/Homebrew/test/diagnostic_spec.rb @@ -122,8 +122,9 @@ describe Homebrew::Diagnostic::Checks do specify "#check_user_path_3" do begin sbin = HOMEBREW_PREFIX/"sbin" - ENV["PATH"] = "#{HOMEBREW_PREFIX}/bin#{File::PATH_SEPARATOR}" + - ENV["PATH"].gsub(/(?:^|#{Regexp.escape(File::PATH_SEPARATOR)})#{Regexp.escape(sbin)}/, "") + ENV["HOMEBREW_PATH"] = + "#{HOMEBREW_PREFIX}/bin#{File::PATH_SEPARATOR}" + + ENV["HOMEBREW_PATH"].gsub(/(?:^|#{Regexp.escape(File::PATH_SEPARATOR)})#{Regexp.escape(sbin)}/, "") (sbin/"something").mkpath expect(subject.check_user_path_1).to be nil @@ -149,7 +150,9 @@ describe Homebrew::Diagnostic::Checks do file = "#{path}/foo-config" FileUtils.touch file FileUtils.chmod 0755, file - ENV["PATH"] = "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" + ENV["HOMEBREW_PATH"] = + ENV["PATH"] = + "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" expect(subject.check_for_config_scripts) .to match('"config" scripts exist') diff --git a/Library/Homebrew/test/requirement_spec.rb b/Library/Homebrew/test/requirement_spec.rb index 110a7ac4f..959041cf4 100644 --- a/Library/Homebrew/test/requirement_spec.rb +++ b/Library/Homebrew/test/requirement_spec.rb @@ -146,17 +146,13 @@ describe Requirement do end describe "#build?" do - context "#build true is specified" do - let(:klass) do - Class.new(described_class) do - build true - end - end + context ":build tag is specified" do + subject { described_class.new([:build]) } it { is_expected.to be_a_build_requirement } end - context "#build ommitted" do + context "#build omitted" do it { is_expected.not_to be_a_build_requirement } end end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index 005c6d2fb..e193b91a0 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -93,6 +93,7 @@ RSpec.configure do |config| HOMEBREW_PREFIX/"opt", HOMEBREW_PREFIX/"Caskroom", HOMEBREW_LIBRARY/"Taps/caskroom", + HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bar", HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bundle", HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo", HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-services", diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index b037068d2..ae1854f58 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -72,6 +72,7 @@ RSpec.shared_context "integration test" do env.merge!( "PATH" => path, + "HOMEBREW_PATH" => path, "HOMEBREW_BREW_FILE" => HOMEBREW_PREFIX/"bin/brew", "HOMEBREW_INTEGRATION_TEST" => command_id_from_args(args), "HOMEBREW_TEST_TMPDIR" => TEST_TMPDIR, diff --git a/Library/Homebrew/test/utils/shell_spec.rb b/Library/Homebrew/test/utils/shell_spec.rb index c44bd8253..d32f9928f 100644 --- a/Library/Homebrew/test/utils/shell_spec.rb +++ b/Library/Homebrew/test/utils/shell_spec.rb @@ -1,92 +1,92 @@ require "utils/shell" describe Utils::Shell do - describe "::shell_profile" do + describe "::profile" do it "returns ~/.bash_profile by default" do ENV["SHELL"] = "/bin/another_shell" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.bash_profile for Sh" do ENV["SHELL"] = "/bin/another_shell" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.bash_profile for Bash" do ENV["SHELL"] = "/bin/bash" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.zshrc for Zsh" do ENV["SHELL"] = "/bin/zsh" - expect(subject.shell_profile).to eq("~/.zshrc") + expect(subject.profile).to eq("~/.zshrc") end it "returns ~/.kshrc for Ksh" do ENV["SHELL"] = "/bin/ksh" - expect(subject.shell_profile).to eq("~/.kshrc") + expect(subject.profile).to eq("~/.kshrc") end end - describe "::path_to_shell" do + describe "::from_path" do it "supports a raw command name" do - expect(subject.path_to_shell("bash")).to eq(:bash) + expect(subject.from_path("bash")).to eq(:bash) end it "supports full paths" do - expect(subject.path_to_shell("/bin/bash")).to eq(:bash) + expect(subject.from_path("/bin/bash")).to eq(:bash) end it "supports versions" do - expect(subject.path_to_shell("zsh-5.2")).to eq(:zsh) + expect(subject.from_path("zsh-5.2")).to eq(:zsh) end it "strips newlines" do - expect(subject.path_to_shell("zsh-5.2\n")).to eq(:zsh) + expect(subject.from_path("zsh-5.2\n")).to eq(:zsh) end it "returns nil when input is invalid" do - expect(subject.path_to_shell("")).to be nil - expect(subject.path_to_shell("@@@@@@")).to be nil - expect(subject.path_to_shell("invalid_shell-4.2")).to be nil + expect(subject.from_path("")).to be nil + expect(subject.from_path("@@@@@@")).to be nil + expect(subject.from_path("invalid_shell-4.2")).to be nil end end specify "::sh_quote" do - expect(subject.sh_quote("")).to eq("''") - expect(subject.sh_quote("\\")).to eq("\\\\") - expect(subject.sh_quote("\n")).to eq("'\n'") - expect(subject.sh_quote("$")).to eq("\\$") - expect(subject.sh_quote("word")).to eq("word") + expect(subject.send(:sh_quote, "")).to eq("''") + expect(subject.send(:sh_quote, "\\")).to eq("\\\\") + expect(subject.send(:sh_quote, "\n")).to eq("'\n'") + expect(subject.send(:sh_quote, "$")).to eq("\\$") + expect(subject.send(:sh_quote, "word")).to eq("word") end specify "::csh_quote" do - expect(subject.csh_quote("")).to eq("''") - expect(subject.csh_quote("\\")).to eq("\\\\") + expect(subject.send(:csh_quote, "")).to eq("''") + expect(subject.send(:csh_quote, "\\")).to eq("\\\\") # note this test is different than for sh - expect(subject.csh_quote("\n")).to eq("'\\\n'") - expect(subject.csh_quote("$")).to eq("\\$") - expect(subject.csh_quote("word")).to eq("word") + expect(subject.send(:csh_quote, "\n")).to eq("'\\\n'") + expect(subject.send(:csh_quote, "$")).to eq("\\$") + expect(subject.send(:csh_quote, "word")).to eq("word") end - describe "::prepend_path_in_shell_profile" do + describe "::prepend_path_in_profile" do let(:path) { "/my/path" } it "supports Tcsh" do ENV["SHELL"] = "/bin/tcsh" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("echo 'setenv PATH #{path}:$") end it "supports Bash" do ENV["SHELL"] = "/bin/bash" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("echo 'export PATH=\"#{path}:$") end it "supports Fish" do ENV["SHELL"] = "/usr/local/bin/fish" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("echo 'set -g fish_user_paths \"#{path}\" $fish_user_paths' >>") end end diff --git a/Library/Homebrew/test/utils_spec.rb b/Library/Homebrew/test/utils_spec.rb index dd7ea20de..ffaa1f493 100644 --- a/Library/Homebrew/test/utils_spec.rb +++ b/Library/Homebrew/test/utils_spec.rb @@ -191,7 +191,7 @@ describe "globally-scoped helper methods" do ENV["HOMEBREW_EDITOR"] = "vemate" ENV["HOMEBREW_PATH"] = dir - editor = dir/"vemate" + editor = "#{dir}/vemate" FileUtils.touch editor FileUtils.chmod 0755, editor @@ -270,4 +270,12 @@ describe "globally-scoped helper methods" do }.to raise_error(MethodDeprecatedError, %r{method.*replacement.*homebrew/homebrew-core.*homebrew/core}m) end end + + describe "#puts_hash" do + it "outputs a hash" do + expect { + puts_hash(a: 1, b: 2, c: [3, { "d"=>4 }]) + }.to output("a: 1\nb: 2\nc: [3, {\"d\"=>4}]\n").to_stdout + end + end end diff --git a/Library/Homebrew/test/version_spec.rb b/Library/Homebrew/test/version_spec.rb index d3d63a25c..41e05019c 100644 --- a/Library/Homebrew/test/version_spec.rb +++ b/Library/Homebrew/test/version_spec.rb @@ -433,6 +433,11 @@ describe Version do .to be_detected_from("https://homebrew.bintray.com/bottles/imagemagick-6.7.5-7.lion.bottle.1.tar.gz") end + specify "date-based version style" do + expect(Version.create("2017-04-17")) + .to be_detected_from("https://example.com/dada-v2017-04-17.tar.gz") + end + specify "dash version style" do expect(Version.create("3.4")) .to be_detected_from("http://www.antlr.org/download/antlr-3.4-complete.jar") diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 7a14916e1..5e0ad5916 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -320,15 +320,24 @@ def which_all(cmd, path = ENV["PATH"]) end def which_editor - editor = ENV.values_at("HOMEBREW_EDITOR", "VISUAL").compact.first - return which(editor, ENV["HOMEBREW_PATH"]) unless editor.nil? + editor = ENV.values_at("HOMEBREW_EDITOR", "VISUAL").compact.reject(&:empty?).first + if editor + editor_name, _, editor_args = editor.partition " " + editor_path = which(editor_name, ENV["HOMEBREW_PATH"]) + editor = if editor_args.to_s.empty? + editor_path.to_s + else + "#{editor_path} #{editor_args}" + end + return editor + end # Find Textmate - editor = "mate" if which "mate" + editor = which("mate", ENV["HOMEBREW_PATH"]) # Find BBEdit / TextWrangler - editor ||= "edit" if which "edit" + editor ||= which("edit", ENV["HOMEBREW_PATH"]) # Find vim - editor ||= "vim" if which "vim" + editor ||= which("vim", ENV["HOMEBREW_PATH"]) # Default to standard vim editor ||= "/usr/bin/vim" @@ -338,7 +347,7 @@ def which_editor or HOMEBREW_EDITOR to your preferred text editor. EOS - editor + editor.to_s end def exec_editor(*args) @@ -406,8 +415,8 @@ def nostdout end end -def paths - @paths ||= ENV["PATH"].split(File::PATH_SEPARATOR).collect do |p| +def paths(env_path = ENV["PATH"]) + @paths ||= env_path.split(File::PATH_SEPARATOR).collect do |p| begin File.expand_path(p).chomp("/") rescue ArgumentError @@ -517,3 +526,19 @@ def migrate_legacy_keg_symlinks_if_necessary end FileUtils.rm_rf legacy_pinned_kegs end + +def puts_hash(hash, indent: 0) + return hash unless hash.is_a? Hash + hash.each do |key, value| + indent_spaces = " " * (indent * 2) + printf "#{indent_spaces}#{key}:" + if value.is_a? Hash + puts + puts_hash(value, indent: indent+1) + else + puts " #{value}" + end + end + hash +end +alias ph puts_hash diff --git a/Library/Homebrew/utils/analytics.sh b/Library/Homebrew/utils/analytics.sh index 35f91eabc..8d5cf2ff7 100644 --- a/Library/Homebrew/utils/analytics.sh +++ b/Library/Homebrew/utils/analytics.sh @@ -85,8 +85,6 @@ report-analytics-screenview-command() { fi # Don't report commands used mostly by our scripts and not users. - # TODO: list more e.g. shell completion things here perhaps using a single - # script as a shell-completion entry point. case "$HOMEBREW_COMMAND" in --prefix|analytics|command|commands) return diff --git a/Library/Homebrew/utils/shell.rb b/Library/Homebrew/utils/shell.rb index 302167d47..5327f6ecf 100644 --- a/Library/Homebrew/utils/shell.rb +++ b/Library/Homebrew/utils/shell.rb @@ -1,62 +1,24 @@ module Utils - SHELL_PROFILE_MAP = { - bash: "~/.bash_profile", - csh: "~/.cshrc", - fish: "~/.config/fish/config.fish", - ksh: "~/.kshrc", - sh: "~/.bash_profile", - tcsh: "~/.tcshrc", - zsh: "~/.zshrc", - }.freeze - module Shell - UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])} + module_function # take a path and heuristically convert it # to a shell name, return nil if there's no match - def path_to_shell(path) + def from_path(path) # we only care about the basename shell_name = File.basename(path) # handle possible version suffix like `zsh-5.2` shell_name.sub!(/-.*\z/m, "") shell_name.to_sym if %w[bash csh fish ksh sh tcsh zsh].include?(shell_name) end - module_function :path_to_shell - - def preferred_shell - path_to_shell(ENV.fetch("SHELL", "")) - end - module_function :preferred_shell - def parent_shell - path_to_shell(`ps -p #{Process.ppid} -o ucomm=`.strip) + def preferred + from_path(ENV.fetch("SHELL", "")) end - module_function :parent_shell - def csh_quote(str) - # ruby's implementation of shell_escape - str = str.to_s - return "''" if str.empty? - str = str.dup - # anything that isn't a known safe character is padded - str.gsub!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") - # newlines have to be specially quoted in csh - str.gsub!(/\n/, "'\\\n'") - str + def parent + from_path(`ps -p #{Process.ppid} -o ucomm=`.strip) end - module_function :csh_quote - - def sh_quote(str) - # ruby's implementation of shell_escape - str = str.to_s - return "''" if str.empty? - str = str.dup - # anything that isn't a known safe character is padded - str.gsub!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") - str.gsub!(/\n/, "'\n'") - str - end - module_function :sh_quote # quote values. quoting keys is overkill def export_value(shell, key, value) @@ -72,24 +34,60 @@ module Utils "setenv #{key} #{csh_quote(value)};" end end - module_function :export_value # return the shell profile file based on users' preferred shell - def shell_profile - SHELL_PROFILE_MAP.fetch(preferred_shell, "~/.bash_profile") + def profile + SHELL_PROFILE_MAP.fetch(preferred, "~/.bash_profile") end - module_function :shell_profile - def prepend_path_in_shell_profile(path) - case preferred_shell + def prepend_path_in_profile(path) + case preferred when :bash, :ksh, :sh, :zsh, nil - "echo 'export PATH=\"#{sh_quote(path)}:$PATH\"' >> #{shell_profile}" + "echo 'export PATH=\"#{sh_quote(path)}:$PATH\"' >> #{profile}" when :csh, :tcsh - "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{shell_profile}" + "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{profile}" when :fish - "echo 'set -g fish_user_paths \"#{sh_quote(path)}\" $fish_user_paths' >> #{shell_profile}" + "echo 'set -g fish_user_paths \"#{sh_quote(path)}\" $fish_user_paths' >> #{profile}" end end - module_function :prepend_path_in_shell_profile + + private + + SHELL_PROFILE_MAP = { + bash: "~/.bash_profile", + csh: "~/.cshrc", + fish: "~/.config/fish/config.fish", + ksh: "~/.kshrc", + sh: "~/.bash_profile", + tcsh: "~/.tcshrc", + zsh: "~/.zshrc", + }.freeze + + UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])} + + module_function + + def csh_quote(str) + # ruby's implementation of shell_escape + str = str.to_s + return "''" if str.empty? + str = str.dup + # anything that isn't a known safe character is padded + str.gsub!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") + # newlines have to be specially quoted in csh + str.gsub!(/\n/, "'\\\n'") + str + end + + def sh_quote(str) + # ruby's implementation of shell_escape + str = str.to_s + return "''" if str.empty? + str = str.dup + # anything that isn't a known safe character is padded + str.gsub!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") + str.gsub!(/\n/, "'\n'") + str + end end end diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index b9f512a50..56ef37f72 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -344,6 +344,11 @@ class Version m = /[-v]((?:\d+\.)*\d+)$/.match(spec_s) return m.captures.first unless m.nil? + # date-based versioning + # e.g. ltopers-v2017-04-14.tar.gz + m = /-v?(\d{4}-\d{2}-\d{2})/.match(stem) + return m.captures.first unless m.nil? + # e.g. lame-398-1 m = /-((?:\d)+-\d+)/.match(stem) return m.captures.first unless m.nil? @@ -44,11 +44,10 @@ fi HOMEBREW_LIBRARY="$HOMEBREW_REPOSITORY/Library" -for VAR in EDITOR PATH +for VAR in EDITOR PATH BINTRAY_USER BINTRAY_KEY do VAR_NEW="HOMEBREW_${VAR}" - # TODO: find a better solution than this. - env | grep -q "$VAR_NEW" && continue + [[ -n "${!VAR_NEW}" ]] && continue export "$VAR_NEW"="${!VAR}" done |
