summaryrefslogtreecommitdiff
path: root/lib/bundler/cli/outdated.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/cli/outdated.rb')
-rw-r--r--lib/bundler/cli/outdated.rb100
1 files changed, 70 insertions, 30 deletions
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index 68c701aefb..465e56ada2 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -26,13 +26,18 @@ module Bundler
def run
check_for_deployment_mode!
- gems.each do |gem_name|
- Bundler::CLI::Common.select_spec(gem_name)
- end
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
Bundler.definition.validate_runtime!
current_specs = Bundler.ui.silence { Bundler.definition.resolve }
+ gems.each do |gem_name|
+ if current_specs[gem_name].empty?
+ raise GemNotFound, "Could not find gem '#{gem_name}'."
+ end
+ end
+
current_dependencies = Bundler.ui.silence do
Bundler.load.dependencies.map {|dep| [dep.name, dep] }.to_h
end
@@ -41,12 +46,12 @@ module Bundler
# We're doing a full update
Bundler.definition(true)
else
- Bundler.definition(:gems => gems, :sources => sources)
+ Bundler.definition(gems: gems, sources: sources)
end
Bundler::CLI::Common.configure_gem_version_promoter(
Bundler.definition,
- options.merge(:strict => @strict)
+ options.merge(strict: @strict)
)
definition_resolution = proc do
@@ -54,7 +59,7 @@ module Bundler
end
if options[:parseable]
- Bundler.ui.silence(&definition_resolution)
+ Bundler.ui.progress(&definition_resolution)
else
definition_resolution.call
end
@@ -90,35 +95,33 @@ module Bundler
end
outdated_gems << {
- :active_spec => active_spec,
- :current_spec => current_spec,
- :dependency => dependency,
- :groups => groups,
+ active_spec: active_spec,
+ current_spec: current_spec,
+ dependency: dependency,
+ groups: groups,
}
end
- if outdated_gems.empty?
+ relevant_outdated_gems = if options_include_groups
+ outdated_gems.group_by {|g| g[:groups] }.sort.flat_map do |groups, gems|
+ contains_group = groups.split(", ").include?(options[:group])
+ next unless options[:groups] || contains_group
+
+ gems
+ end.compact
+ else
+ outdated_gems
+ end
+
+ if relevant_outdated_gems.empty?
unless options[:parseable]
Bundler.ui.info(nothing_outdated_message)
end
else
- if options_include_groups
- relevant_outdated_gems = outdated_gems.group_by {|g| g[:groups] }.sort.flat_map do |groups, gems|
- contains_group = groups.split(", ").include?(options[:group])
- next unless options[:groups] || contains_group
-
- gems
- end.compact
-
- if options[:parseable]
- print_gems(relevant_outdated_gems)
- else
- print_gems_table(relevant_outdated_gems)
- end
- elsif options[:parseable]
- print_gems(outdated_gems)
+ if options[:parseable]
+ print_gems(relevant_outdated_gems)
else
- print_gems_table(outdated_gems)
+ print_gems_table(relevant_outdated_gems)
end
exit 1
@@ -155,7 +158,7 @@ module Bundler
return active_spec if strict
- active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.installable_on_platform?(current_spec.platform) }.sort_by(&:version)
if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
end
@@ -199,7 +202,15 @@ module Bundler
end
spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \
- "installed #{current_version}#{dependency_version})"
+ "installed #{current_version}#{dependency_version}"
+
+ release_date = release_date_for(active_spec)
+ spec_outdated_info += ", released #{release_date}" unless release_date.empty?
+
+ remaining = cooldown_days_remaining(active_spec)
+ spec_outdated_info += ", in cooldown for #{remaining} more day#{"s" if remaining > 1}" if remaining
+
+ spec_outdated_info += ")"
output_message = if options[:parseable]
spec_outdated_info.to_s
@@ -215,13 +226,25 @@ module Bundler
def gem_column_for(current_spec, active_spec, dependency, groups)
current_version = "#{current_spec.version}#{current_spec.git_version}"
spec_version = "#{active_spec.version}#{active_spec.git_version}"
+ remaining = cooldown_days_remaining(active_spec)
+ spec_version += " (cooldown #{remaining}d)" if remaining
dependency = dependency.requirement if dependency
ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s]
+ ret_val << release_date_for(active_spec)
ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug?
ret_val
end
+ def cooldown_days_remaining(spec, now = Time.now)
+ return nil unless spec.respond_to?(:created_at) && spec.created_at
+ return nil unless spec.respond_to?(:remote) && spec.remote
+ days = spec.remote.effective_cooldown
+ return nil if days.nil? || days <= 0
+ remaining = days - ((now - spec.created_at) / 86_400.0)
+ remaining > 0 ? remaining.ceil : nil
+ end
+
def check_for_deployment_mode!
return unless Bundler.frozen_bundle?
suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
@@ -283,11 +306,28 @@ module Bundler
end
def table_header
- header = ["Gem", "Current", "Latest", "Requested", "Groups"]
+ header = ["Gem", "Current", "Latest", "Requested", "Groups", "Release Date"]
header << "Path" if Bundler.ui.debug?
header
end
+ def release_date_for(spec)
+ return "" unless spec.respond_to?(:date)
+
+ date = spec.date
+ return "" unless date
+
+ return "" unless Gem.const_defined?(:DEFAULT_SOURCE_DATE_EPOCH)
+ default_date = Time.at(Gem::DEFAULT_SOURCE_DATE_EPOCH).utc
+ default_date = Time.utc(default_date.year, default_date.month, default_date.day)
+
+ date = date.utc if date.respond_to?(:utc)
+
+ return "" if date == default_date
+
+ date.strftime("%Y-%m-%d")
+ end
+
def justify(row, sizes)
row.each_with_index.map do |element, index|
element.ljust(sizes[index])