diff options
Diffstat (limited to 'lib/bundler/cli/common.rb')
| -rw-r--r-- | lib/bundler/cli/common.rb | 93 |
1 files changed, 76 insertions, 17 deletions
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb index 9d40ee9dfd..b44fbc3096 100644 --- a/lib/bundler/cli/common.rb +++ b/lib/bundler/cli/common.rb @@ -2,6 +2,12 @@ module Bundler module CLI::Common + def self.validate_cooldown!(value) + return if value.nil? + return if value.is_a?(Integer) && value >= 0 + raise InvalidOption, "Expected `--cooldown` to be a non-negative integer, got #{value.inspect}" + end + def self.output_post_install_messages(messages) return if Bundler.settings["ignore_messages"] messages.to_a.each do |name, msg| @@ -14,17 +20,38 @@ module Bundler Bundler.ui.info msg end - def self.output_without_groups_message + def self.output_fund_metadata_summary + return if Bundler.settings["ignore_funding_requests"] + definition = Bundler.definition + current_dependencies = definition.requested_dependencies + current_specs = definition.specs + + count = current_dependencies.count {|dep| current_specs[dep.name].first.metadata.key?("funding_uri") } + + return if count.zero? + + intro = count > 1 ? "#{count} installed gems you directly depend on are" : "#{count} installed gem you directly depend on is" + message = "#{intro} looking for funding.\n Run `bundle fund` for details" + Bundler.ui.info message + end + + def self.output_without_groups_message(command) return if Bundler.settings[:without].empty? - Bundler.ui.confirm without_groups_message + Bundler.ui.confirm without_groups_message(command) end - def self.without_groups_message + def self.without_groups_message(command) + command_in_past_tense = command == :install ? "installed" : "updated" groups = Bundler.settings[:without] + "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}." + end + + def self.verbalize_groups(groups) + groups.map! {|g| "'#{g}'" } group_list = [groups[0...-1].join(", "), groups[-1..-1]]. reject {|s| s.to_s.empty? }.join(" and ") - group_str = (groups.size == 1) ? "group" : "groups" - "Gems in the #{group_str} #{group_list} were not installed." + group_str = groups.size == 1 ? "group" : "groups" + "#{group_str} #{group_list}" end def self.select_spec(name, regex_match = nil) @@ -33,12 +60,21 @@ module Bundler Bundler.definition.specs.each do |spec| return spec if spec.name == name - specs << spec if regexp && spec.name =~ regexp + specs << spec if regexp && spec.name.match?(regexp) end + default_spec = default_gem_spec(name) + specs << default_spec if default_spec + case specs.count when 0 - raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) + dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name } + + if dep_in_other_group + raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored." + else + raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) + end when 1 specs.first else @@ -48,11 +84,12 @@ module Bundler raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) end - def self.ask_for_spec_from(specs) - if !$stdout.tty? && ENV["BUNDLE_SPEC_RUN"].nil? - raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) - end + def self.default_gem_spec(name) + gem_spec = Gem::Specification.find_all_by_name(name).last + gem_spec if gem_spec&.default_gem? + end + def self.ask_for_spec_from(specs) specs.each_with_index do |spec, index| Bundler.ui.info "#{index.succ} : #{spec.name}", true end @@ -63,16 +100,21 @@ module Bundler end def self.gem_not_found_message(missing_gem_name, alternatives) - require "bundler/similarity_detector" message = "Could not find gem '#{missing_gem_name}'." alternate_names = alternatives.map {|a| a.respond_to?(:name) ? a.name : a } - suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name) - message += "\nDid you mean #{suggestions}?" if suggestions + if alternate_names.include?(missing_gem_name.downcase) + message += "\nDid you mean '#{missing_gem_name.downcase}'?" + elsif defined?(DidYouMean::SpellChecker) + suggestions = DidYouMean::SpellChecker.new(dictionary: alternate_names).correct(missing_gem_name) + message += "\nDid you mean #{word_list(suggestions)}?" unless suggestions.empty? + end message end def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems) - locked_names = locked_gems.specs.map(&:name) + return unless locked_gems + + locked_names = locked_gems.specs.map(&:name).uniq names.-(locked_names).each do |g| raise GemNotFound, gem_not_found_message(g, locked_names) end @@ -80,10 +122,13 @@ module Bundler def self.configure_gem_version_promoter(definition, options) patch_level = patch_level_options(options) + patch_level << :patch if patch_level.empty? && Bundler.settings[:prefer_patch] raise InvalidOption, "Provide only one of the following options: #{patch_level.join(", ")}" unless patch_level.length <= 1 + definition.gem_version_promoter.tap do |gvp| gvp.level = patch_level.first || :major - gvp.strict = options[:strict] || options["update-strict"] + gvp.strict = options[:strict] || options["filter-strict"] + gvp.pre = options[:pre] end end @@ -94,9 +139,23 @@ module Bundler def self.clean_after_install? clean = Bundler.settings[:clean] return clean unless clean.nil? - clean ||= Bundler.feature_flag.auto_clean_without_path? && Bundler.settings[:path].nil? + clean ||= Bundler.feature_flag.bundler_5_mode? && Bundler.settings[:path].nil? clean &&= !Bundler.use_system_gems? clean end + + def self.word_list(words) + if words.empty? + return "" + end + + words = words.map {|word| "'#{word}'" } + + if words.length == 1 + return words[0] + end + + [words[0..-2].join(", "), words[-1]].join(" or ") + end end end |
